aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-04-19 22:54:31 +0000
committerDouglas Gregor <dgregor@apple.com>2010-04-19 22:54:31 +0000
commit16573fa9705b546b7597c273b25b85d6321e2b33 (patch)
tree16ffff74e94aea37c3456a4807d7a3282694e366
parent63c323d7584e3d91549fae23fb30b426d3b19042 (diff)
Keep track of the actual storage specifier written on a variable or
function declaration, since it may end up being changed (e.g., "extern" can become "static" if a prior declaration was static). Patch by Enea Zaffanella and Paolo Bolzoni. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@101826 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/Decl.h37
-rw-r--r--include/clang/AST/DeclCXX.h14
-rw-r--r--include/clang/AST/DeclTemplate.h3
-rw-r--r--include/clang/Parse/DeclSpec.h10
-rw-r--r--lib/AST/ASTImporter.cpp5
-rw-r--r--lib/AST/Decl.cpp18
-rw-r--r--lib/AST/DeclCXX.cpp14
-rw-r--r--lib/CodeGen/CGBlocks.cpp22
-rw-r--r--lib/CodeGen/CGClass.cpp1
-rw-r--r--lib/Frontend/PCHReaderDecl.cpp6
-rw-r--r--lib/Frontend/PCHWriterDecl.cpp3
-rw-r--r--lib/Frontend/RewriteObjC.cpp47
-rw-r--r--lib/Parse/DeclSpec.cpp1
-rw-r--r--lib/Sema/Sema.h3
-rw-r--r--lib/Sema/SemaDecl.cpp115
-rw-r--r--lib/Sema/SemaDeclAttr.cpp3
-rw-r--r--lib/Sema/SemaDeclCXX.cpp9
-rw-r--r--lib/Sema/SemaDeclObjC.cpp2
-rw-r--r--lib/Sema/SemaExprCXX.cpp4
-rw-r--r--lib/Sema/SemaObjCProperty.cpp1
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp3
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp15
-rw-r--r--lib/Sema/TreeTransform.h1
23 files changed, 230 insertions, 107 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 17ac81a5ae..626657dfa7 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -490,6 +490,7 @@ protected:
private:
// FIXME: This can be packed into the bitfields in Decl.
unsigned SClass : 3;
+ unsigned SClassAsWritten : 3;
bool ThreadSpecified : 1;
bool HasCXXDirectInit : 1;
@@ -500,11 +501,13 @@ private:
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;
@@ -521,7 +524,8 @@ public:
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();
@@ -529,7 +533,11 @@ public:
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 {
@@ -862,7 +870,7 @@ class ImplicitParamDecl : public VarDecl {
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,
@@ -884,9 +892,9 @@ class ParmVarDecl : public VarDecl {
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);
}
@@ -894,7 +902,8 @@ public:
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);
@@ -1020,6 +1029,7 @@ private:
// 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;
@@ -1060,11 +1070,11 @@ private:
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),
@@ -1089,7 +1099,9 @@ public:
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,
@@ -1244,6 +1256,11 @@ public:
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; }
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 29587a9b01..ba6f31cff8 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -936,15 +936,16 @@ class CXXMethodDecl : public FunctionDecl {
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; }
@@ -1187,7 +1188,8 @@ class CXXConstructorDecl : public CXXMethodDecl {
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);
@@ -1330,7 +1332,8 @@ class CXXDestructorDecl : public CXXMethodDecl {
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);
}
@@ -1386,7 +1389,8 @@ class CXXConversionDecl : public CXXMethodDecl {
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:
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 9f8d88fd49..da501e95b1 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -727,7 +727,8 @@ class NonTypeTemplateParmDecl
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)
{ }
diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h
index e83edbb301..6642e1b9f4 100644
--- a/include/clang/Parse/DeclSpec.h
+++ b/include/clang/Parse/DeclSpec.h
@@ -185,6 +185,8 @@ private:
// 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.
@@ -217,6 +219,9 @@ private:
WrittenBuiltinSpecs writtenBS;
void SaveWrittenBuiltinSpecs();
+ void SaveStorageSpecifierAsWritten() {
+ StorageClassSpecAsWritten = StorageClassSpec;
+ }
DeclSpec(const DeclSpec&); // DO NOT IMPLEMENT
void operator=(const DeclSpec&); // DO NOT IMPLEMENT
@@ -238,6 +243,7 @@ public:
FS_explicit_specified(false),
Friend_specified(false),
Constexpr_specified(false),
+ StorageClassSpecAsWritten(SCS_unspecified),
TypeRep(0),
AttrList(0),
ProtocolQualifiers(0),
@@ -335,6 +341,10 @@ public:
///
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 {
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index b13e7f91fc..5651121402 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -1905,6 +1905,7 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
} else {
ToFunction = FunctionDecl::Create(Importer.getToContext(), DC, Loc,
Name, T, TInfo, D->getStorageClass(),
+ D->getStorageClassAsWritten(),
D->isInlineSpecified(),
D->hasWrittenPrototype());
}
@@ -2125,7 +2126,8 @@ Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
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());
@@ -2197,6 +2199,7 @@ Decl *ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) {
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);
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index d4cc945b1b..b02cbdeb26 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -586,8 +586,8 @@ const char *VarDecl::getStorageClassSpecifierString(StorageClass SC) {
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) {
@@ -811,8 +811,10 @@ void VarDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK,
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() {
@@ -1658,10 +1660,10 @@ FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC,
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;
}
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 28489d39c5..eef067b0d8 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -587,9 +587,9 @@ CXXMethodDecl *
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 {
@@ -745,11 +745,12 @@ CXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
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 {
@@ -848,8 +849,7 @@ CXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
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
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
index 509734123b..2997b21915 100644
--- a/lib/CodeGen/CGBlocks.cpp
+++ b/lib/CodeGen/CGBlocks.cpp
@@ -812,7 +812,8 @@ CharUnits BlockFunction::getBlockOffset(const BlockDeclRefExpr *BDRE) {
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());
@@ -860,7 +861,9 @@ GenerateCopyHelperFunction(bool BlockHasCopyDispose, const llvm::StructType *T,
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());
@@ -941,8 +944,9 @@ GenerateDestroyHelperFunction(bool BlockHasCopyDispose,
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) {
@@ -1025,8 +1029,9 @@ GeneratebyrefCopyHelperFunction(const llvm::Type *T, int flag) {
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
@@ -1089,8 +1094,9 @@ BlockFunction::GeneratebyrefDestroyHelperFunction(const llvm::Type *T,
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);
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp
index 7ca8f29b7e..42b0591f38 100644
--- a/lib/CodeGen/CGClass.cpp
+++ b/lib/CodeGen/CGClass.cpp
@@ -1380,6 +1380,7 @@ CodeGenFunction::GenerateCXXAggrDestructorHelper(const CXXDestructorDecl *D,
getContext().getTranslationUnitDecl(),
SourceLocation(), II, R, 0,
FunctionDecl::Static,
+ FunctionDecl::None,
false, true);
StartFunction(FD, R, Fn, Args, SourceLocation());
QualType BaseElementTy = getContext().getBaseElementType(Array);
diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp
index 8a11f11a6c..45f7e496ba 100644
--- a/lib/Frontend/PCHReaderDecl.cpp
+++ b/lib/Frontend/PCHReaderDecl.cpp
@@ -179,6 +179,7 @@ void PCHDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
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++]);
@@ -399,6 +400,7 @@ void PCHDeclReader::VisitFieldDecl(FieldDecl *FD) {
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++]);
@@ -746,7 +748,7 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
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:
@@ -755,7 +757,7 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
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);
diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp
index 536c2c6a6f..6b4ba67904 100644
--- a/lib/Frontend/PCHWriterDecl.cpp
+++ b/lib/Frontend/PCHWriterDecl.cpp
@@ -176,6 +176,7 @@ void PCHDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
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());
@@ -383,6 +384,7 @@ void PCHDeclWriter::VisitFieldDecl(FieldDecl *D) {
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());
@@ -494,6 +496,7 @@ void PCHWriter::WriteDeclsBlockAbbrevs() {
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
diff --git a/lib/Frontend/RewriteObjC.cpp b/lib/Frontend/RewriteObjC.cpp
index 87272ebe9f..804a5d0b9d 100644
--- a/lib/Frontend/RewriteObjC.cpp
+++ b/lib/Frontend/RewriteObjC.cpp
@@ -2269,7 +2269,8 @@ void RewriteObjC::SynthSelGetUidFunctionDecl() {
SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
SelGetUidIdent, getFuncType, 0,
- FunctionDecl::Extern, false);
+ FunctionDecl::Extern,
+ FunctionDecl::None, false);
}
void RewriteObjC::RewriteFunctionDecl(FunctionDecl *FD) {
@@ -2366,7 +2367,8 @@ void RewriteObjC::SynthSuperContructorFunctionDecl() {
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, ...);
@@ -2387,7 +2389,8 @@ void RewriteObjC::SynthMsgSendFunctionDecl() {
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, ...);
@@ -2411,7 +2414,8 @@ void RewriteObjC::SynthMsgSendSuperFunctionDecl() {
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, ...);
@@ -2432,7 +2436,8 @@ void RewriteObjC::SynthMsgSendStretFunctionDecl() {
MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
msgSendIdent, msgSendType, 0,
- FunctionDecl::Extern, false);
+ FunctionDecl::Extern,
+ FunctionDecl::None, false);
}
// SynthMsgSendSuperStretFunctionDecl -
@@ -2458,7 +2463,8 @@ void RewriteObjC::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, ...);
@@ -2479,7 +2485,8 @@ void RewriteObjC::SynthMsgSendFpretFunctionDecl() {
MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
msgSendIdent, msgSendType, 0,
- FunctionDecl::Extern, false);
+ FunctionDecl::Extern,
+ FunctionDecl::None, false);
}
// SynthGetClassFunctionDecl - id objc_getClass(const char *name);
@@ -2495,7 +2502,8 @@ void RewriteObjC::SynthGetClassFunctionDecl() {
GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
getClassIdent, getClassType, 0,
- FunctionDecl::Extern, false);
+ FunctionDecl::Extern,
+ FunctionDecl::None, false);
}
// SynthGetSuperClassFunctionDecl - Class class_getSuperclass(Class cls);
@@ -2510,9 +2518,12 @@ void RewriteObjC::SynthGetSuperClassFunctionDecl() {
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);
@@ -2528,7 +2539,8 @@ void RewriteObjC::SynthGetMetaClassFunctionDecl() {
GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
getClassIdent, getClassType, 0,
- FunctionDecl::Extern, false);
+ FunctionDecl::Extern,
+ FunctionDecl::None, false);
}
Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
@@ -2562,7 +2574,7 @@ 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()),
@@ -3074,7 +3086,8 @@ Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) {
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()),
@@ -5070,8 +5083,8 @@ FunctionDecl *RewriteObjC::SynthBlockInitFunctionDecl(const char *name) {
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,
@@ -5151,7 +5164,7 @@ 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()),
diff --git a/lib/Parse/DeclSpec.cpp b/lib/Parse/DeclSpec.cpp
index 11865ab97b..5dc08b3dfa 100644
--- a/lib/Parse/DeclSpec.cpp
+++ b/lib/Pars