From c4df407604b8798dfc56b2692d25b13a11fda0db Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Mon, 19 Apr 2010 22:54:31 +0000 Subject: [PATCH] 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. llvm-svn: 101826 --- clang/include/clang/AST/Decl.h | 37 ++++-- clang/include/clang/AST/DeclCXX.h | 14 ++- clang/include/clang/AST/DeclTemplate.h | 3 +- clang/include/clang/Parse/DeclSpec.h | 10 ++ clang/lib/AST/ASTImporter.cpp | 5 +- clang/lib/AST/Decl.cpp | 18 +-- clang/lib/AST/DeclCXX.cpp | 14 +-- clang/lib/CodeGen/CGBlocks.cpp | 22 ++-- clang/lib/CodeGen/CGClass.cpp | 1 + clang/lib/Frontend/PCHReaderDecl.cpp | 6 +- clang/lib/Frontend/PCHWriterDecl.cpp | 3 + clang/lib/Frontend/RewriteObjC.cpp | 47 ++++--- clang/lib/Parse/DeclSpec.cpp | 1 + clang/lib/Sema/Sema.h | 3 +- clang/lib/Sema/SemaDecl.cpp | 115 ++++++++++++------ clang/lib/Sema/SemaDeclAttr.cpp | 3 +- clang/lib/Sema/SemaDeclCXX.cpp | 9 +- clang/lib/Sema/SemaDeclObjC.cpp | 2 +- clang/lib/Sema/SemaExprCXX.cpp | 4 +- clang/lib/Sema/SemaObjCProperty.cpp | 1 + clang/lib/Sema/SemaTemplateInstantiate.cpp | 3 +- .../lib/Sema/SemaTemplateInstantiateDecl.cpp | 15 ++- clang/lib/Sema/TreeTransform.h | 1 + 23 files changed, 230 insertions(+), 107 deletions(-) diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 17ac81a5ae38..626657dfa766 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/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 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/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index 29587a9b018b..ba6f31cff8e8 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/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/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index 9f8d88fd49a1..da501e95b1fc 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/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/clang/include/clang/Parse/DeclSpec.h b/clang/include/clang/Parse/DeclSpec.h index e83edbb30180..6642e1b9f4fd 100644 --- a/clang/include/clang/Parse/DeclSpec.h +++ b/clang/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/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index b13e7f91fc6e..5651121402e7 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/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/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index d4cc945b1ba0..b02cbdeb262e 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/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/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 28489d39c565..eef067b0d890 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/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/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp index 509734123b0c..2997b21915f5 100644 --- a/clang/lib/CodeGen/CGBlocks.cpp +++ b/clang/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/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 7ca8f29b7e9a..42b0591f3844 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/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/clang/lib/Frontend/PCHReaderDecl.cpp b/clang/lib/Frontend/PCHReaderDecl.cpp index 8a11f11a6c45..45f7e496ba55 100644 --- a/clang/lib/Frontend/PCHReaderDecl.cpp +++ b/clang/lib/Frontend/PCHReaderDecl.cpp @@ -179,6 +179,7 @@ void PCHDeclReader::VisitFunctionDecl(FunctionDecl *FD) { FD->setPreviousDeclaration( cast_or_null(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/clang/lib/Frontend/PCHWriterDecl.cpp b/clang/lib/Frontend/PCHWriterDecl.cpp index 536c2c6a6fdf..6b4ba67904f1 100644 --- a/clang/lib/Frontend/PCHWriterDecl.cpp +++ b/clang/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/clang/lib/Frontend/RewriteObjC.cpp b/clang/lib/Frontend/RewriteObjC.cpp index 87272ebe9f23..804a5d0b9da1 100644 --- a/clang/lib/Frontend/RewriteObjC.cpp +++ b/clang/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/clang/lib/Parse/DeclSpec.cpp b/clang/lib/Parse/DeclSpec.cpp index 11865ab97b84..5dc08b3dfa2c 100644 --- a/clang/lib/Parse/DeclSpec.cpp +++ b/clang/lib/Parse/DeclSpec.cpp @@ -433,6 +433,7 @@ void DeclSpec::SaveWrittenBuiltinSpecs() { 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(); diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index e057a924c75b..a95d08262e76 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -810,7 +810,8 @@ public: 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, diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 115b7bf756e1..9ef03591187a 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -717,7 +717,8 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, FunctionDecl *New = FunctionDecl::Create(Context, Context.getTranslationUnitDecl(), Loc, II, R, /*TInfo=*/0, - FunctionDecl::Extern, false, + FunctionDecl::Extern, + FunctionDecl::None, false, /*hasPrototype=*/true); New->setImplicit(); @@ -728,7 +729,7 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, 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()); } @@ -1160,7 +1161,8 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) { 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); } @@ -1592,6 +1594,44 @@ bool Sema::InjectAnonymousStructOrUnionMembers(Scope *S, DeclContext *Owner, 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 @@ -1712,29 +1752,25 @@ Sema::DeclPtrTy Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, if (getLangOptions().CPlusPlus) FieldCollector->Add(cast(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(); @@ -2332,24 +2368,20 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC, 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) { @@ -2423,8 +2455,8 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC, } } - 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(); @@ -2802,6 +2834,10 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, 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. @@ -2862,7 +2898,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, // 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(); } @@ -2911,7 +2947,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, // This is a C++ method declaration. NewFD = CXXMethodDecl::Create(Context, cast(DC), D.getIdentifierLoc(), Name, R, TInfo, - isStatic, isInline); + isStatic, SCAsWritten, isInline); isVirtualOkay = !isStatic; } else { @@ -2928,7 +2964,8 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, NewFD = FunctionDecl::Create(Context, DC, D.getIdentifierLoc(), - Name, R, TInfo, SC, isInline, HasPrototype); + Name, R, TInfo, SC, SCAsWritten, isInline, + HasPrototype); } if (D.isInvalidType()) @@ -3128,6 +3165,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, ParmVarDecl *Param = ParmVarDecl::Create(Context, NewFD, SourceLocation(), 0, *AI, /*TInfo=*/0, + VarDecl::None, VarDecl::None, 0); Param->setImplicit(); Params.push_back(Param); @@ -4088,8 +4126,10 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { // 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); @@ -4147,7 +4187,8 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { // 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(); @@ -4176,10 +4217,12 @@ ParmVarDecl *Sema::CheckParameter(DeclContext *DC, 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 diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 6a1451a4c6c7..1c07d9b365b3 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -1978,7 +1978,8 @@ NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) { 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(NewD); NewVD->setQualifierInfo(VD->getQualifier(), VD->getQualifierRange()); diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index c6fd53ca613c..c8a3a8ab33b2 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -2385,6 +2385,7 @@ void Sema::AddImplicitlyDeclaredMembersToClass(Scope *S, ClassDecl->getLocation(), /*IdentifierInfo=*/0, ArgType, /*TInfo=*/0, + VarDecl::None, VarDecl::None, 0); CopyConstructor->setParams(&FromParam, 1); if (S) @@ -2464,7 +2465,9 @@ void Sema::AddImplicitlyDeclaredMembersToClass(Scope *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()); @@ -2475,6 +2478,7 @@ void Sema::AddImplicitlyDeclaredMembersToClass(Scope *S, ClassDecl->getLocation(), /*IdentifierInfo=*/0, ArgType, /*TInfo=*/0, + VarDecl::None, VarDecl::None, 0); CopyAssignment->setParams(&FromParam, 1); @@ -4787,7 +4791,8 @@ VarDecl *Sema::BuildExceptionDeclaration(Scope *S, QualType ExDeclType, 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()) { diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index cc1aab4d89d4..e1973fa5c208 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -1565,7 +1565,7 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration( 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, diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index aa9efed6da15..9440772fc6e4 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1208,7 +1208,8 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name, 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) @@ -1216,6 +1217,7 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name, ParmVarDecl *Param = ParmVarDecl::Create(Context, Alloc, SourceLocation(), 0, Argument, /*TInfo=*/0, + VarDecl::None, VarDecl::None, 0); Alloc->setParams(&Param, 1); diff --git a/clang/lib/Sema/SemaObjCProperty.cpp b/clang/lib/Sema/SemaObjCProperty.cpp index c73d81505993..d47d6c2994fb 100644 --- a/clang/lib/Sema/SemaObjCProperty.cpp +++ b/clang/lib/Sema/SemaObjCProperty.cpp @@ -953,6 +953,7 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property, property->getType(), /*TInfo=*/0, VarDecl::None, + VarDecl::None, 0); SetterMethod->setMethodParams(Context, &Argument, 1, 1); CD->addDecl(SetterMethod); diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index a2bd37c0bbbc..e35d988dc816 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -991,7 +991,8 @@ ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm, NewDI, NewDI->getType(), OldParm->getIdentifier(), OldParm->getLocation(), - OldParm->getStorageClass()); + OldParm->getStorageClass(), + OldParm->getStorageClassAsWritten()); if (!NewParm) return 0; diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 18b6829744f0..10fe176148f0 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -322,7 +322,8 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) { 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()); @@ -991,7 +992,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, 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) @@ -1210,14 +1211,16 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, Constructor->getLocation(), Name, T, TInfo, Constructor->isExplicit(), - Constructor->isInlineSpecified(), false); + Constructor->isInlineSpecified(), + false); } else if (CXXDestructorDecl *Destructor = dyn_cast(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(D)) { CanQualType ConvTy = SemaRef.Context.getCanonicalType( @@ -1232,7 +1235,9 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, } 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) diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index f9ffd3f41aa5..e2fdf66442d4 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -2630,6 +2630,7 @@ TreeTransform::TransformFunctionTypeParam(ParmVarDecl *OldParm) { NewDI->getType(), NewDI, OldParm->getStorageClass(), + OldParm->getStorageClassAsWritten(), /* DefArg */ NULL); }