private:
// FIXME: This can be packed into the bitfields in Decl.
unsigned SClass : 3;
+ unsigned SClassAsWritten : 3;
bool ThreadSpecified : 1;
bool HasCXXDirectInit : 1;
friend class StmtIteratorBase;
protected:
VarDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
- QualType T, TypeSourceInfo *TInfo, StorageClass SC)
+ QualType T, TypeSourceInfo *TInfo, StorageClass SC,
+ StorageClass SCAsWritten)
: DeclaratorDecl(DK, DC, L, Id, T, TInfo), Init(),
ThreadSpecified(false), HasCXXDirectInit(false),
DeclaredInCondition(false) {
SClass = SC;
+ SClassAsWritten = SCAsWritten;
}
typedef Redeclarable<VarDecl> redeclarable_base;
static VarDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
- QualType T, TypeSourceInfo *TInfo, StorageClass S);
+ QualType T, TypeSourceInfo *TInfo, StorageClass S,
+ StorageClass SCAsWritten);
virtual void Destroy(ASTContext& C);
virtual ~VarDecl();
virtual SourceRange getSourceRange() const;
StorageClass getStorageClass() const { return (StorageClass)SClass; }
+ StorageClass getStorageClassAsWritten() const {
+ return (StorageClass) SClassAsWritten;
+ }
void setStorageClass(StorageClass SC) { SClass = SC; }
+ void setStorageClassAsWritten(StorageClass SC) { SClassAsWritten = SC; }
void setThreadSpecified(bool T) { ThreadSpecified = T; }
bool isThreadSpecified() const {
protected:
ImplicitParamDecl(Kind DK, DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, QualType Tw)
- : VarDecl(DK, DC, L, Id, Tw, /*TInfo=*/0, VarDecl::None) {}
+ : VarDecl(DK, DC, L, Id, Tw, /*TInfo=*/0, VarDecl::None, VarDecl::None) {}
public:
static ImplicitParamDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
protected:
ParmVarDecl(Kind DK, DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
- StorageClass S, Expr *DefArg)
- : VarDecl(DK, DC, L, Id, T, TInfo, S),
- objcDeclQualifier(OBJC_TQ_None), HasInheritedDefaultArg(false) {
+ StorageClass S, StorageClass SCAsWritten, Expr *DefArg)
+ : VarDecl(DK, DC, L, Id, T, TInfo, S, SCAsWritten),
+ objcDeclQualifier(OBJC_TQ_None), HasInheritedDefaultArg(false) {
setDefaultArg(DefArg);
}
static ParmVarDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo,
- StorageClass S, Expr *DefArg);
+ StorageClass S, StorageClass SCAsWritten,
+ Expr *DefArg);
ObjCDeclQualifier getObjCDeclQualifier() const {
return ObjCDeclQualifier(objcDeclQualifier);
// FIXME: This can be packed into the bitfields in Decl.
// NOTE: VC++ treats enums as signed, avoid using the StorageClass enum
unsigned SClass : 2;
+ unsigned SClassAsWritten : 2;
bool IsInline : 1;
bool IsVirtualAsWritten : 1;
bool IsPure : 1;
protected:
FunctionDecl(Kind DK, DeclContext *DC, SourceLocation L,
DeclarationName N, QualType T, TypeSourceInfo *TInfo,
- StorageClass S, bool isInline)
+ StorageClass S, StorageClass SCAsWritten, bool isInline)
: DeclaratorDecl(DK, DC, L, N, T, TInfo),
DeclContext(DK),
ParamInfo(0), Body(),
- SClass(S), IsInline(isInline),
+ SClass(S), SClassAsWritten(SCAsWritten), IsInline(isInline),
IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false),
HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false),
IsCopyAssignment(false),
static FunctionDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
DeclarationName N, QualType T,
TypeSourceInfo *TInfo,
- StorageClass S = None, bool isInline = false,
+ StorageClass S = None,
+ StorageClass SCAsWritten = None,
+ bool isInline = false,
bool hasWrittenPrototype = true);
virtual void getNameForDiagnostic(std::string &S,
StorageClass getStorageClass() const { return StorageClass(SClass); }
void setStorageClass(StorageClass SC) { SClass = SC; }
+ StorageClass getStorageClassAsWritten() const {
+ return StorageClass(SClassAsWritten);
+ }
+ void setStorageClassAsWritten(StorageClass SC) { SClassAsWritten = SC; }
+
/// \brief Determine whether the "inline" keyword was specified for this
/// function.
bool isInlineSpecified() const { return IsInline; }
protected:
CXXMethodDecl(Kind DK, CXXRecordDecl *RD, SourceLocation L,
DeclarationName N, QualType T, TypeSourceInfo *TInfo,
- bool isStatic, bool isInline)
+ bool isStatic, StorageClass SCAsWritten, bool isInline)
: FunctionDecl(DK, RD, L, N, T, TInfo, (isStatic ? Static : None),
- isInline) {}
+ SCAsWritten, isInline) {}
public:
static CXXMethodDecl *Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, DeclarationName N,
QualType T, TypeSourceInfo *TInfo,
bool isStatic = false,
+ StorageClass SCAsWritten = FunctionDecl::None,
bool isInline = false);
bool isStatic() const { return getStorageClass() == Static; }
DeclarationName N, QualType T, TypeSourceInfo *TInfo,
bool isExplicitSpecified, bool isInline,
bool isImplicitlyDeclared)
- : CXXMethodDecl(CXXConstructor, RD, L, N, T, TInfo, false, isInline),
+ : CXXMethodDecl(CXXConstructor, RD, L, N, T, TInfo, false,
+ FunctionDecl::None, isInline),
IsExplicitSpecified(isExplicitSpecified), ImplicitlyDefined(false),
BaseOrMemberInitializers(0), NumBaseOrMemberInitializers(0) {
setImplicit(isImplicitlyDeclared);
CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation L,
DeclarationName N, QualType T,
bool isInline, bool isImplicitlyDeclared)
- : CXXMethodDecl(CXXDestructor, RD, L, N, T, /*TInfo=*/0, false, isInline),
+ : CXXMethodDecl(CXXDestructor, RD, L, N, T, /*TInfo=*/0, false,
+ FunctionDecl::None, isInline),
ImplicitlyDefined(false), OperatorDelete(0) {
setImplicit(isImplicitlyDeclared);
}
CXXConversionDecl(CXXRecordDecl *RD, SourceLocation L,
DeclarationName N, QualType T, TypeSourceInfo *TInfo,
bool isInline, bool isExplicitSpecified)
- : CXXMethodDecl(CXXConversion, RD, L, N, T, TInfo, false, isInline),
+ : CXXMethodDecl(CXXConversion, RD, L, N, T, TInfo, false,
+ FunctionDecl::None, isInline),
IsExplicitSpecified(isExplicitSpecified) { }
public:
NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
unsigned P, IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo)
- : VarDecl(NonTypeTemplateParm, DC, L, Id, T, TInfo, VarDecl::None),
+ : VarDecl(NonTypeTemplateParm, DC, L, Id, T, TInfo, VarDecl::None,
+ VarDecl::None),
TemplateParmPosition(D, P), DefaultArgument(0)
{ }
// constexpr-specifier
bool Constexpr_specified : 1;
+ /*SCS*/unsigned StorageClassSpecAsWritten : 3;
+
/// TypeRep - This contains action-specific information about a specific TST.
/// For example, for a typedef or struct, it might contain the declaration for
/// these.
WrittenBuiltinSpecs writtenBS;
void SaveWrittenBuiltinSpecs();
+ void SaveStorageSpecifierAsWritten() {
+ StorageClassSpecAsWritten = StorageClassSpec;
+ }
DeclSpec(const DeclSpec&); // DO NOT IMPLEMENT
void operator=(const DeclSpec&); // DO NOT IMPLEMENT
FS_explicit_specified(false),
Friend_specified(false),
Constexpr_specified(false),
+ StorageClassSpecAsWritten(SCS_unspecified),
TypeRep(0),
AttrList(0),
ProtocolQualifiers(0),
///
unsigned getParsedSpecifiers() const;
+ SCS getStorageClassSpecAsWritten() const {
+ return (SCS)StorageClassSpecAsWritten;
+ }
+
/// isEmpty - Return true if this declaration specifier is completely empty:
/// no tokens were parsed in the production of it.
bool isEmpty() const {
} else {
ToFunction = FunctionDecl::Create(Importer.getToContext(), DC, Loc,
Name, T, TInfo, D->getStorageClass(),
+ D->getStorageClassAsWritten(),
D->isInlineSpecified(),
D->hasWrittenPrototype());
}
TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
VarDecl *ToVar = VarDecl::Create(Importer.getToContext(), DC, Loc,
Name.getAsIdentifierInfo(), T, TInfo,
- D->getStorageClass());
+ D->getStorageClass(),
+ D->getStorageClassAsWritten());
// Import the qualifier, if any.
if (D->getQualifier()) {
NestedNameSpecifier *NNS = Importer.Import(D->getQualifier());
ParmVarDecl *ToParm = ParmVarDecl::Create(Importer.getToContext(), DC,
Loc, Name.getAsIdentifierInfo(),
T, TInfo, D->getStorageClass(),
+ D->getStorageClassAsWritten(),
/*FIXME: Default argument*/ 0);
ToParm->setHasInheritedDefaultArg(D->hasInheritedDefaultArg());
return Importer.Imported(D, ToParm);
VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
- StorageClass S) {
- return new (C) VarDecl(Var, DC, L, Id, T, TInfo, S);
+ StorageClass S, StorageClass SCAsWritten) {
+ return new (C) VarDecl(Var, DC, L, Id, T, TInfo, S, SCAsWritten);
}
void VarDecl::Destroy(ASTContext& C) {
ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo,
- StorageClass S, Expr *DefArg) {
- return new (C) ParmVarDecl(ParmVar, DC, L, Id, T, TInfo, S, DefArg);
+ StorageClass S, StorageClass SCAsWritten,
+ Expr *DefArg) {
+ return new (C) ParmVarDecl(ParmVar, DC, L, Id, T, TInfo,
+ S, SCAsWritten, DefArg);
}
Expr *ParmVarDecl::getDefaultArg() {
SourceLocation L,
DeclarationName N, QualType T,
TypeSourceInfo *TInfo,
- StorageClass S, bool isInline,
- bool hasWrittenPrototype) {
- FunctionDecl *New
- = new (C) FunctionDecl(Function, DC, L, N, T, TInfo, S, isInline);
+ StorageClass S, StorageClass SCAsWritten,
+ bool isInline, bool hasWrittenPrototype) {
+ FunctionDecl *New = new (C) FunctionDecl(Function, DC, L, N, T, TInfo,
+ S, SCAsWritten, isInline);
New->HasWrittenPrototype = hasWrittenPrototype;
return New;
}
CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, DeclarationName N,
QualType T, TypeSourceInfo *TInfo,
- bool isStatic, bool isInline) {
+ bool isStatic, StorageClass SCAsWritten, bool isInline) {
return new (C) CXXMethodDecl(CXXMethod, RD, L, N, T, TInfo,
- isStatic, isInline);
+ isStatic, SCAsWritten, isInline);
}
bool CXXMethodDecl::isUsualDeallocationFunction() const {
SourceLocation L, DeclarationName N,
QualType T, TypeSourceInfo *TInfo,
bool isExplicit,
- bool isInline, bool isImplicitlyDeclared) {
+ bool isInline,
+ bool isImplicitlyDeclared) {
assert(N.getNameKind() == DeclarationName::CXXConstructorName &&
"Name must refer to a constructor");
- return new (C) CXXConstructorDecl(RD, L, N, T, TInfo, isExplicit, isInline,
- isImplicitlyDeclared);
+ return new (C) CXXConstructorDecl(RD, L, N, T, TInfo, isExplicit,
+ isInline, isImplicitlyDeclared);
}
bool CXXConstructorDecl::isDefaultConstructor() const {
bool isImplicitlyDeclared) {
assert(N.getNameKind() == DeclarationName::CXXDestructorName &&
"Name must refer to a destructor");
- return new (C) CXXDestructorDecl(RD, L, N, T, isInline,
- isImplicitlyDeclared);
+ return new (C) CXXDestructorDecl(RD, L, N, T, isInline, isImplicitlyDeclared);
}
void
Pad.getQuantity()),
ArrayType::Normal, 0);
ValueDecl *PadDecl = VarDecl::Create(getContext(), 0, SourceLocation(),
- 0, QualType(PadTy), 0, VarDecl::None);
+ 0, QualType(PadTy), 0,
+ VarDecl::None, VarDecl::None);
Expr *E;
E = new (getContext()) DeclRefExpr(PadDecl, PadDecl->getType(),
SourceLocation());
FunctionDecl *FD = FunctionDecl::Create(getContext(),
getContext().getTranslationUnitDecl(),
SourceLocation(), II, R, 0,
- FunctionDecl::Static, false,
+ FunctionDecl::Static,
+ FunctionDecl::None,
+ false,
true);
CGF.StartFunction(FD, R, Fn, Args, SourceLocation());
FunctionDecl *FD = FunctionDecl::Create(getContext(),
getContext().getTranslationUnitDecl(),
SourceLocation(), II, R, 0,
- FunctionDecl::Static, false,
- true);
+ FunctionDecl::Static,
+ FunctionDecl::None,
+ false, true);
CGF.StartFunction(FD, R, Fn, Args, SourceLocation());
if (NoteForHelperp) {
FunctionDecl *FD = FunctionDecl::Create(getContext(),
getContext().getTranslationUnitDecl(),
SourceLocation(), II, R, 0,
- FunctionDecl::Static, false,
- true);
+ FunctionDecl::Static,
+ FunctionDecl::None,
+ false, true);
CGF.StartFunction(FD, R, Fn, Args, SourceLocation());
// dst->x
FunctionDecl *FD = FunctionDecl::Create(getContext(),
getContext().getTranslationUnitDecl(),
SourceLocation(), II, R, 0,
- FunctionDecl::Static, false,
- true);
+ FunctionDecl::Static,
+ FunctionDecl::None,
+ false, true);
CGF.StartFunction(FD, R, Fn, Args, SourceLocation());
llvm::Value *V = CGF.GetAddrOfLocalVar(Src);
getContext().getTranslationUnitDecl(),
SourceLocation(), II, R, 0,
FunctionDecl::Static,
+ FunctionDecl::None,
false, true);
StartFunction(FD, R, Fn, Args, SourceLocation());
QualType BaseElementTy = getContext().getBaseElementType(Array);
FD->setPreviousDeclaration(
cast_or_null<FunctionDecl>(Reader.GetDecl(Record[Idx++])));
FD->setStorageClass((FunctionDecl::StorageClass)Record[Idx++]);
+ FD->setStorageClassAsWritten((FunctionDecl::StorageClass)Record[Idx++]);
FD->setInlineSpecified(Record[Idx++]);
FD->setVirtualAsWritten(Record[Idx++]);
FD->setPure(Record[Idx++]);
void PCHDeclReader::VisitVarDecl(VarDecl *VD) {
VisitDeclaratorDecl(VD);
VD->setStorageClass((VarDecl::StorageClass)Record[Idx++]);
+ VD->setStorageClassAsWritten((VarDecl::StorageClass)Record[Idx++]);
VD->setThreadSpecified(Record[Idx++]);
VD->setCXXDirectInitializer(Record[Idx++]);
VD->setDeclaredInCondition(Record[Idx++]);
break;
case pch::DECL_VAR:
D = VarDecl::Create(*Context, 0, SourceLocation(), 0, QualType(), 0,
- VarDecl::None);
+ VarDecl::None, VarDecl::None);
break;
case pch::DECL_IMPLICIT_PARAM:
case pch::DECL_PARM_VAR:
D = ParmVarDecl::Create(*Context, 0, SourceLocation(), 0, QualType(), 0,
- VarDecl::None, 0);
+ VarDecl::None, VarDecl::None, 0);
break;
case pch::DECL_FILE_SCOPE_ASM:
D = FileScopeAsmDecl::Create(*Context, 0, SourceLocation(), 0);
Writer.AddStmt(D->getBody());
Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
Record.push_back(D->getStorageClass()); // FIXME: stable encoding
+ Record.push_back(D->getStorageClassAsWritten());
Record.push_back(D->isInlineSpecified());
Record.push_back(D->isVirtualAsWritten());
Record.push_back(D->isPure());
void PCHDeclWriter::VisitVarDecl(VarDecl *D) {
VisitDeclaratorDecl(D);
Record.push_back(D->getStorageClass()); // FIXME: stable encoding
+ Record.push_back(D->getStorageClassAsWritten());
Record.push_back(D->isThreadSpecified());
Record.push_back(D->hasCXXDirectInitializer());
Record.push_back(D->isDeclaredInCondition());
Abv->Add(BitCodeAbbrevOp(pch::PREDEF_TYPE_NULL_ID)); // InfoType
// VarDecl
Abv->Add(BitCodeAbbrevOp(0)); // StorageClass
+ Abv->Add(BitCodeAbbrevOp(0)); // StorageClassAsWritten
Abv->Add(BitCodeAbbrevOp(0)); // isThreadSpecified
Abv->Add(BitCodeAbbrevOp(0)); // hasCXXDirectInitializer
Abv->Add(BitCodeAbbrevOp(0)); // isDeclaredInCondition
SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
SelGetUidIdent, getFuncType, 0,
- FunctionDecl::Extern, false);
+ FunctionDecl::Extern,
+ FunctionDecl::None, false);
}
void RewriteObjC::RewriteFunctionDecl(FunctionDecl *FD) {
SuperContructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
msgSendIdent, msgSendType, 0,
- FunctionDecl::Extern, false);
+ FunctionDecl::Extern,
+ FunctionDecl::None, false);
}
// SynthMsgSendFunctionDecl - id objc_msgSend(id self, SEL op, ...);
MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
msgSendIdent, msgSendType, 0,
- FunctionDecl::Extern, false);
+ FunctionDecl::Extern,
+ FunctionDecl::None, false);
}
// SynthMsgSendSuperFunctionDecl - id objc_msgSendSuper(struct objc_super *, SEL op, ...);
MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
msgSendIdent, msgSendType, 0,
- FunctionDecl::Extern, false);
+ FunctionDecl::Extern,
+ FunctionDecl::None, false);
}
// SynthMsgSendStretFunctionDecl - id objc_msgSend_stret(id self, SEL op, ...);
MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
msgSendIdent, msgSendType, 0,
- FunctionDecl::Extern, false);
+ FunctionDecl::Extern,
+ FunctionDecl::None, false);
}
// SynthMsgSendSuperStretFunctionDecl -
MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
msgSendIdent, msgSendType, 0,
- FunctionDecl::Extern, false);
+ FunctionDecl::Extern,
+ FunctionDecl::None, false);
}
// SynthMsgSendFpretFunctionDecl - double objc_msgSend_fpret(id self, SEL op, ...);
MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
msgSendIdent, msgSendType, 0,
- FunctionDecl::Extern, false);
+ FunctionDecl::Extern,
+ FunctionDecl::None, false);
}
// SynthGetClassFunctionDecl - id objc_getClass(const char *name);
GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
getClassIdent, getClassType, 0,
- FunctionDecl::Extern, false);
+ FunctionDecl::Extern,
+ FunctionDecl::None, false);
}
// SynthGetSuperClassFunctionDecl - Class class_getSuperclass(Class cls);
false, false, 0, 0,
FunctionType::ExtInfo());
GetSuperClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
- SourceLocation(),
- getSuperClassIdent, getClassType, 0,
- FunctionDecl::Extern, false);
+ SourceLocation(),
+ getSuperClassIdent,
+ getClassType, 0,
+ FunctionDecl::Extern,
+ FunctionDecl::None,
+ false);
}
// SynthGetMetaClassFunctionDecl - id objc_getClass(const char *name);
GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
getClassIdent, getClassType, 0,
- FunctionDecl::Extern, false);
+ FunctionDecl::Extern,
+ FunctionDecl::None, false);
}
Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
&Context->Idents.get(S), strType, 0,
- VarDecl::Static);
+ VarDecl::Static, VarDecl::None);
DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, strType, SourceLocation());
Expr *Unop = new (Context) UnaryOperator(DRE, UnaryOperator::AddrOf,
Context->getPointerType(DRE->getType()),
std::string Name = "_OBJC_PROTOCOL_" + Exp->getProtocol()->getNameAsString();
IdentifierInfo *ID = &Context->Idents.get(Name);
VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
- ID, getProtocolType(), 0, VarDecl::Extern);
+ ID, getProtocolType(), 0,
+ VarDecl::Extern, VarDecl::None);
DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, getProtocolType(), SourceLocation());
Expr *DerefExpr = new (Context) UnaryOperator(DRE, UnaryOperator::AddrOf,
Context->getPointerType(DRE->getType()),
IdentifierInfo *ID = &Context->Idents.get(name);
QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy);
return FunctionDecl::Create(*Context, TUDecl,SourceLocation(),
- ID, FType, 0, FunctionDecl::Extern, false,
- false);
+ ID, FType, 0, FunctionDecl::Extern,
+ FunctionDecl::None, false, false);
}
Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp,
VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
&Context->Idents.get(DescData.c_str()),
Context->VoidPtrTy, 0,
- VarDecl::Static);
+ VarDecl::Static, VarDecl::None);
UnaryOperator *DescRefExpr = new (Context) UnaryOperator(
new (Context) DeclRefExpr(NewVD,
Context->VoidPtrTy, SourceLocation()),
void DeclSpec::Finish(Diagnostic &D, Preprocessor &PP) {
// Before possibly changing their values, save specs as written.
SaveWrittenBuiltinSpecs();
+ SaveStorageSpecifierAsWritten();
// Check the type specifier components first.
SourceManager &SrcMgr = PP.getSourceManager();
TypeSourceInfo *TSInfo, QualType T,
IdentifierInfo *Name,
SourceLocation NameLoc,
- VarDecl::StorageClass StorageClass);
+ VarDecl::StorageClass StorageClass,
+ VarDecl::StorageClass StorageClassAsWritten);
virtual void ActOnObjCCatchParam(DeclPtrTy D);
virtual void ActOnParamDefaultArgument(DeclPtrTy param,
SourceLocation EqualLoc,
FunctionDecl *New = FunctionDecl::Create(Context,
Context.getTranslationUnitDecl(),
Loc, II, R, /*TInfo=*/0,
- FunctionDecl::Extern, false,
+ FunctionDecl::Extern,
+ FunctionDecl::None, false,
/*hasPrototype=*/true);
New->setImplicit();
for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i)
Params.push_back(ParmVarDecl::Create(Context, New, SourceLocation(), 0,
FT->getArgType(i), /*TInfo=*/0,
- VarDecl::None, 0));
+ VarDecl::None, VarDecl::None, 0));
New->setParams(Params.data(), Params.size());
}
ParmVarDecl *Param = ParmVarDecl::Create(Context, New,
SourceLocation(), 0,
*ParamType, /*TInfo=*/0,
- VarDecl::None, 0);
+ VarDecl::None, VarDecl::None,
+ 0);
Param->setImplicit();
Params.push_back(Param);
}
return Invalid;
}
+/// StorageClassSpecToVarDeclStorageClass - Maps a DeclSpec::SCS to
+/// a VarDecl::StorageClass. Any error reporting is up to the caller:
+/// illegal input values are mapped to VarDecl::None.
+static VarDecl::StorageClass
+StorageClassSpecToVarDeclStorageClass(DeclSpec::SCS StorageClassSpec) {
+ switch (StorageClassSpec) {
+ case DeclSpec::SCS_unspecified: return VarDecl::None;
+ case DeclSpec::SCS_extern: return VarDecl::Extern;
+ case DeclSpec::SCS_static: return VarDecl::Static;
+ case DeclSpec::SCS_auto: return VarDecl::Auto;
+ case DeclSpec::SCS_register: return VarDecl::Register;
+ case DeclSpec::SCS_private_extern: return VarDecl::PrivateExtern;
+ // Illegal SCSs map to None: error reporting is up to the caller.
+ case DeclSpec::SCS_mutable: // Fall through.
+ case DeclSpec::SCS_typedef: return VarDecl::None;
+ }
+ llvm_unreachable("unknown storage class specifier");
+}
+
+/// StorageClassSpecToFunctionDeclStorageClass - Maps a DeclSpec::SCS to
+/// a FunctionDecl::StorageClass. Any error reporting is up to the caller:
+/// illegal input values are mapped to FunctionDecl::None.
+static FunctionDecl::StorageClass
+StorageClassSpecToFunctionDeclStorageClass(DeclSpec::SCS StorageClassSpec) {
+ switch (StorageClassSpec) {
+ case DeclSpec::SCS_unspecified: return FunctionDecl::None;
+ case DeclSpec::SCS_extern: return FunctionDecl::Extern;
+ case DeclSpec::SCS_static: return FunctionDecl::Static;
+ case DeclSpec::SCS_private_extern: return FunctionDecl::PrivateExtern;
+ // Illegal SCSs map to None: error reporting is up to the caller.
+ case DeclSpec::SCS_auto: // Fall through.
+ case DeclSpec::SCS_mutable: // Fall through.
+ case DeclSpec::SCS_register: // Fall through.
+ case DeclSpec::SCS_typedef: return FunctionDecl::None;
+ }
+ llvm_unreachable("unknown storage class specifier");
+}
+
/// ActOnAnonymousStructOrUnion - Handle the declaration of an
/// anonymous structure or union. Anonymous unions are a C++ feature
/// (C++ [class.union]) and a GNU C extension; anonymous structures
if (getLangOptions().CPlusPlus)
FieldCollector->Add(cast<FieldDecl>(Anon));
} else {
- VarDecl::StorageClass SC;
- switch (DS.getStorageClassSpec()) {
- default: assert(0 && "Unknown storage class!");
- case DeclSpec::SCS_unspecified: SC = VarDecl::None; break;
- case DeclSpec::SCS_extern: SC = VarDecl::Extern; break;
- case DeclSpec::SCS_static: SC = VarDecl::Static; break;
- case DeclSpec::SCS_auto: SC = VarDecl::Auto; break;
- case DeclSpec::SCS_register: SC = VarDecl::Register; break;
- case DeclSpec::SCS_private_extern: SC = VarDecl::PrivateExtern; break;
- case DeclSpec::SCS_mutable:
+ DeclSpec::SCS SCSpec = DS.getStorageClassSpec();
+ assert(SCSpec != DeclSpec::SCS_typedef &&
+ "Parser allowed 'typedef' as storage class VarDecl.");
+ VarDecl::StorageClass SC = StorageClassSpecToVarDeclStorageClass(SCSpec);
+ if (SCSpec == DeclSpec::SCS_mutable) {
// mutable can only appear on non-static class members, so it's always
// an error here
Diag(Record->getLocation(), diag::err_mutable_nonmember);
Invalid = true;
SC = VarDecl::None;
- break;
}
+ SCSpec = DS.getStorageClassSpecAsWritten();
+ VarDecl::StorageClass SCAsWritten
+ = StorageClassSpecToVarDeclStorageClass(SCSpec);
Anon = VarDecl::Create(Context, Owner, Record->getLocation(),
/*IdentifierInfo=*/0,
Context.getTypeDeclType(Record),
- TInfo,
- SC);
+ TInfo, SC, SCAsWritten);
}
Anon->setImplicit();
if (getLangOptions().CPlusPlus)
CheckExtraCXXDefaultArguments(D);
- VarDecl *NewVD;
- VarDecl::StorageClass SC;
- switch (D.getDeclSpec().getStorageClassSpec()) {
- default: assert(0 && "Unknown storage class!");
- case DeclSpec::SCS_unspecified: SC = VarDecl::None; break;
- case DeclSpec::SCS_extern: SC = VarDecl::Extern; break;
- case DeclSpec::SCS_static: SC = VarDecl::Static; break;
- case DeclSpec::SCS_auto: SC = VarDecl::Auto; break;
- case DeclSpec::SCS_register: SC = VarDecl::Register; break;
- case DeclSpec::SCS_private_extern: SC = VarDecl::PrivateExtern; break;
- case DeclSpec::SCS_mutable:
+ DeclSpec::SCS SCSpec = D.getDeclSpec().getStorageClassSpec();
+ assert(SCSpec != DeclSpec::SCS_typedef &&
+ "Parser allowed 'typedef' as storage class VarDecl.");
+ VarDecl::StorageClass SC = StorageClassSpecToVarDeclStorageClass(SCSpec);
+ if (SCSpec == DeclSpec::SCS_mutable) {
// mutable can only appear on non-static class members, so it's always
// an error here
Diag(D.getIdentifierLoc(), diag::err_mutable_nonmember);
D.setInvalidType();
SC = VarDecl::None;
- break;
}
+ SCSpec = D.getDeclSpec().getStorageClassSpecAsWritten();
+ VarDecl::StorageClass SCAsWritten
+ = StorageClassSpecToVarDeclStorageClass(SCSpec);
IdentifierInfo *II = Name.getAsIdentifierInfo();
if (!II) {
}
}
- NewVD = VarDecl::Create(Context, DC, D.getIdentifierLoc(),
- II, R, TInfo, SC);
+ VarDecl *NewVD = VarDecl::Create(Context, DC, D.getIdentifierLoc(),
+ II, R, TInfo, SC, SCAsWritten);
if (D.isInvalidType())
NewVD->setInvalidDecl();
bool isVirtual = D.getDeclSpec().isVirtualSpecified();
bool isExplicit = D.getDeclSpec().isExplicitSpecified();
+ DeclSpec::SCS SCSpec = D.getDeclSpec().getStorageClassSpecAsWritten();
+ FunctionDecl::StorageClass SCAsWritten
+ = StorageClassSpecToFunctionDeclStorageClass(SCSpec);
+
// Check that the return type is not an abstract class type.
// For record types, this is done by the AbstractClassUsageDiagnoser once
// the class has been completely parsed.
// Create a FunctionDecl to satisfy the function definition parsing
// code path.
NewFD = FunctionDecl::Create(Context, DC, D.getIdentifierLoc(),
- Name, R, TInfo, SC, isInline,
+ Name, R, TInfo, SC, SCAsWritten, isInline,
/*hasPrototype=*/true);
D.setInvalidType();
}
// This is a C++ method declaration.
NewFD = CXXMethodDecl::Create(Context, cast<CXXRecordDecl>(DC),
D.getIdentifierLoc(), Name, R, TInfo,
- isStatic, isInline);
+ isStatic, SCAsWritten, isInline);
isVirtualOkay = !isStatic;
} else {
NewFD = FunctionDecl::Create(Context, DC,
D.getIdentifierLoc(),
- Name, R, TInfo, SC, isInline, HasPrototype);
+ Name, R, TInfo, SC, SCAsWritten, isInline,
+ HasPrototype);
}
if (D.isInvalidType())
ParmVarDecl *Param = ParmVarDecl::Create(Context, NewFD,
SourceLocation(), 0,
*AI, /*TInfo=*/0,
+ VarDecl::None,
VarDecl::None, 0);
Param->setImplicit();
Params.push_back(Param);
// Verify C99 6.7.5.3p2: The only SCS allowed is 'register'.
VarDecl::StorageClass StorageClass = VarDecl::None;
+ VarDecl::StorageClass StorageClassAsWritten = VarDecl::None;
if (DS.getStorageClassSpec() == DeclSpec::SCS_register) {
StorageClass = VarDecl::Register;
+ StorageClassAsWritten = VarDecl::Register;
} else if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified) {
Diag(DS.getStorageClassSpecLoc(),
diag::err_invalid_storage_class_in_func_decl);
// looking like class members in C++.
ParmVarDecl *New = CheckParameter(Context.getTranslationUnitDecl(),
TInfo, parmDeclType, II,
- D.getIdentifierLoc(), StorageClass);
+ D.getIdentifierLoc(),
+ StorageClass, StorageClassAsWritten);
if (D.isInvalidType())
New->setInvalidDecl();
TypeSourceInfo *TSInfo, QualType T,
IdentifierInfo *Name,
SourceLocation NameLoc,
- VarDecl::StorageClass StorageClass) {
+ VarDecl::StorageClass StorageClass,
+ VarDecl::StorageClass StorageClassAsWritten) {
ParmVarDecl *New = ParmVarDecl::Create(Context, DC, NameLoc, Name,
adjustParameterType(T), TSInfo,
- StorageClass, 0);
+ StorageClass, StorageClassAsWritten,
+ 0);
// Parameters can not be abstract class types.
// For record types, this is done by the AbstractClassUsageDiagnoser once
NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
VD->getLocation(), II,
VD->getType(), VD->getTypeSourceInfo(),
- VD->getStorageClass());
+ VD->getStorageClass(),
+ VD->getStorageClassAsWritten());
if (VD->getQualifier()) {
VarDecl *NewVD = cast<VarDecl>(NewD);
NewVD->setQualifierInfo(VD->getQualifier(), VD->getQualifierRange());
ClassDecl->getLocation(),
/*IdentifierInfo=*/0,
ArgType, /*TInfo=*/0,
+ VarDecl::None,
VarDecl::None, 0);
CopyConstructor->setParams(&FromParam, 1);
if (S)
/*FIXME:*/false,
false, 0, 0,
FunctionType::ExtInfo()),
- /*TInfo=*/0, /*isStatic=*/false, /*isInline=*/true);
+ /*TInfo=*/0, /*isStatic=*/false,
+ /*StorageClassAsWritten=*/FunctionDecl::None,
+ /*isInline=*/true);
CopyAssignment->setAccess(AS_public);
CopyAssignment->setImplicit();
CopyAssignment->setTrivial(ClassDecl->hasTrivialCopyAssignment());
ClassDecl->getLocation(),
/*IdentifierInfo=*/0,
ArgType, /*TInfo=*/0,
+ VarDecl::None,
VarDecl::None, 0);
CopyAssignment->setParams(&FromParam, 1);
Invalid = true;
VarDecl *ExDecl = VarDecl::Create(Context, CurContext, Loc,
- Name, ExDeclType, TInfo, VarDecl::None);
+ Name, ExDeclType, TInfo, VarDecl::None,
+ VarDecl::None);
if (!Invalid) {
if (const RecordType *RecordTy = ExDeclType->getAs<RecordType>()) {
ParmVarDecl* Param
= ParmVarDecl::Create(Context, ObjCMethod, ArgInfo[i].NameLoc,
ArgInfo[i].Name, ArgType, DI,
- VarDecl::None, 0);
+ VarDecl::None, VarDecl::None, 0);
if (ArgType->isObjCInterfaceType()) {
Diag(ArgInfo[i].NameLoc,
FunctionType::ExtInfo());
FunctionDecl *Alloc =
FunctionDecl::Create(Context, GlobalCtx, SourceLocation(), Name,
- FnType, /*TInfo=*/0, FunctionDecl::None, false, true);
+ FnType, /*TInfo=*/0, FunctionDecl::None,
+ FunctionDecl::None, false, true);
Alloc->setImplicit();
if (AddMallocAttr)
ParmVarDecl *Param = ParmVarDecl::Create(Context, Alloc, SourceLocation(),
0, Argument, /*TInfo=*/0,
+ VarDecl::None,
VarDecl::None, 0);
Alloc->setParams(&Param, 1);
property->getType(),
/*TInfo=*/0,
VarDecl::None,
+ VarDecl::None,
0);
SetterMethod->setMethodParams(Context, &Argument, 1, 1);
CD->addDecl(SetterMethod);
NewDI, NewDI->getType(),
OldParm->getIdentifier(),
OldParm->getLocation(),
- OldParm->getStorageClass());
+ OldParm->getStorageClass(),
+ OldParm->getStorageClassAsWritten());
if (!NewParm)
return 0;
VarDecl *Var = VarDecl::Create(SemaRef.Context, Owner,
D->getLocation(), D->getIdentifier(),
DI->getType(), DI,
- D->getStorageClass());
+ D->getStorageClass(),
+ D->getStorageClassAsWritten());
Var->setThreadSpecified(D->isThreadSpecified());
Var->setCXXDirectInitializer(D->hasCXXDirectInitializer());
Var->setDeclaredInCondition(D->isDeclaredInCondition());
FunctionDecl *Function =
FunctionDecl::Create(SemaRef.Context, DC, D->getLocation(),
D->getDeclName(), T, TInfo,
- D->getStorageClass(),
+ D->getStorageClass(), D->getStorageClassAsWritten(),
D->isInlineSpecified(), D->hasWrittenPrototype());
if (Qualifier)
Constructor->getLocation(),
Name, T, TInfo,
Constructor->isExplicit(),
- Constructor->isInlineSpecified(), false);
+ Constructor->isInlineSpecified(),
+ false);
} else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) {
QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
Name = SemaRef.Context.DeclarationNames.getCXXDestructorName(
SemaRef.Context.getCanonicalType(ClassTy));
Method = CXXDestructorDecl::Create(SemaRef.Context, Record,
Destructor->getLocation(), Name,
- T, Destructor->isInlineSpecified(), false);
+ T, Destructor->isInlineSpecified(),
+ false);
} else if (CXXConversionDecl *Conversion = dyn_cast<CXXConversionDecl>(D)) {
CanQualType ConvTy
= SemaRef.Context.getCanonicalType(
} else {
Method = CXXMethodDecl::Create(SemaRef.Context, Record, D->getLocation(),
D->getDeclName(), T, TInfo,
- D->isStatic(), D->isInlineSpecified());
+ D->isStatic(),
+ D->getStorageClassAsWritten(),
+ D->isInlineSpecified());
}
if (Qualifier)
NewDI->getType(),
NewDI,
OldParm->getStorageClass(),
+ OldParm->getStorageClassAsWritten(),
/* DefArg */ NULL);
}