diff options
-rw-r--r-- | include/clang/AST/Decl.h | 4 | ||||
-rw-r--r-- | include/clang/AST/DeclCXX.h | 7 | ||||
-rw-r--r-- | include/clang/AST/DeclarationName.h | 3 | ||||
-rw-r--r-- | include/clang/Basic/DiagnosticKinds.def | 2 | ||||
-rw-r--r-- | include/clang/Basic/IdentifierTable.h | 22 | ||||
-rw-r--r-- | include/clang/Parse/DeclSpec.h | 26 | ||||
-rw-r--r-- | lib/AST/Decl.cpp | 52 | ||||
-rw-r--r-- | lib/AST/DeclCXX.cpp | 5 | ||||
-rw-r--r-- | lib/AST/DeclarationName.cpp | 46 | ||||
-rw-r--r-- | lib/Basic/IdentifierTable.cpp | 30 | ||||
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 10 | ||||
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 2 | ||||
-rw-r--r-- | lib/Parse/Parser.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 3 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 88 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 18 | ||||
-rw-r--r-- | test/SemaCXX/conversion-function.cpp | 2 | ||||
-rw-r--r-- | test/SemaCXX/overloaded-operator-decl.cpp | 5 |
18 files changed, 160 insertions, 167 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 2ac94a9bdf..8e688fec5d 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -100,7 +100,7 @@ public: /// expensive string manipulation, so it should be called only when /// absolutely critical. For simple declarations, @c /// getIdentifierName() should suffice. - std::string getName() const; + std::string getName() const { return Name.getAsString(); } static bool classof(const Decl *D) { return D->getKind() >= NamedFirst && D->getKind() <= NamedLast; @@ -558,7 +558,7 @@ protected: public: static FunctionDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, - IdentifierInfo *Id, QualType T, + DeclarationName N, QualType T, StorageClass S = None, bool isInline = false, ScopedDecl *PrevDecl = 0, SourceLocation TSStartLoc = SourceLocation()); diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 8edfc650a4..86cd68ac8e 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -58,6 +58,11 @@ public: isa<CXXConversionDecl>(FD) || isa<CXXConstructorDecl>(FD)) && "Overloaded functions must have the same name"); Functions.push_back(FD); + + // An overloaded function declaration always has the location of + // the most-recently-added function declaration. + if (FD->getLocation().isValid()) + this->setLocation(FD->getLocation()); } function_iterator function_begin() { return Functions.begin(); } @@ -396,7 +401,7 @@ protected: public: static CXXMethodDecl *Create(ASTContext &C, CXXRecordDecl *RD, - SourceLocation L, IdentifierInfo *Id, + SourceLocation L, DeclarationName N, QualType T, bool isStatic = false, bool isInline = false, ScopedDecl *PrevDecl = 0); diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h index 909255c349..877d23566b 100644 --- a/include/clang/AST/DeclarationName.h +++ b/include/clang/AST/DeclarationName.h @@ -164,6 +164,9 @@ public: /// getNameKind - Determine what kind of name this is. NameKind getNameKind() const; + /// getName - Retrieve the human-readable string for this name. + std::string getAsString() const; + /// getAsIdentifierInfo - Retrieve the IdentifierInfo * stored in /// this declaration name, or NULL if this declaration name isn't a /// simple identifier. diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def index c232eaa449..d427e69ac7 100644 --- a/include/clang/Basic/DiagnosticKinds.def +++ b/include/clang/Basic/DiagnosticKinds.def @@ -660,6 +660,8 @@ DIAG(ext_anon_param_requires_type_specifier, EXTENSION, "type specifier required for unnamed parameter, defaults to int") DIAG(err_missing_param, ERROR, "expected parameter declarator") +DIAG(err_bad_variable_name, ERROR, + "'%0' cannot be the name of a variable or data member") DIAG(err_declarator_need_ident, ERROR, "declarator requires an identifier") diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h index a13d4ba538..58ad133e3b 100644 --- a/include/clang/Basic/IdentifierTable.h +++ b/include/clang/Basic/IdentifierTable.h @@ -179,16 +179,6 @@ class IdentifierTable { /// overloadable operators in C++. IdentifierInfo *OverloadedOperators[NUM_OVERLOADED_OPERATORS]; - /// ConstructorId - Placeholder identifier for C++ constructors. - IdentifierInfo *ConstructorId; - - /// DestructorId - Placeholder identifier for C++ destructor. - IdentifierInfo *DestructorId; - - /// ConversionFunctionId - Placeholder identifier for a C++ - /// conversion function. - IdentifierInfo *ConversionFunctionId; - public: /// IdentifierTable ctor - Create the identifier table, populating it with /// info about the language keywords for the language specified by LangOpts. @@ -214,18 +204,6 @@ public: return *OverloadedOperators[Op]; } - /// getConstructorId - Return a placeholder identifier for a C++ - /// constructor. - IdentifierInfo &getConstructorId(); - - /// getDestructorId - Return a placeholder identifier for a C++ - /// destructor. - IdentifierInfo &getDestructorId(); - - /// getConversionFunctionId - Return a placeholder identifier for a - /// C++ conversion function. - IdentifierInfo &getConversionFunctionId(); - typedef HashTableTy::const_iterator iterator; typedef HashTableTy::const_iterator const_iterator; diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h index d1b887ff30..46629637bc 100644 --- a/include/clang/Parse/DeclSpec.h +++ b/include/clang/Parse/DeclSpec.h @@ -767,7 +767,12 @@ public: /// isPastIdentifier - Return true if we have parsed beyond the point where /// the bool isPastIdentifier() const { return IdentifierLoc.isValid(); } - + + /// hasName - Whether this declarator has a name, which might be an + /// identifier (accessible via getIdentifier()) or some kind of + /// special C++ name (constructor, destructor, etc.). + bool hasName() const { return getKind() != DK_Abstract; } + IdentifierInfo *getIdentifier() const { return Identifier; } SourceLocation getIdentifierLoc() const { return IdentifierLoc; } @@ -780,31 +785,26 @@ public: Kind = DK_Abstract; } - /// SetConstructor - Set this declarator to be a C++ constructor + /// setConstructor - Set this declarator to be a C++ constructor /// declarator. - void SetConstructor(Action::TypeTy *Ty, IdentifierInfo *ID, - SourceLocation Loc) { - Identifier = ID; + void setConstructor(Action::TypeTy *Ty, SourceLocation Loc) { IdentifierLoc = Loc; Kind = DK_Constructor; Type = Ty; } - /// SetDestructor - Set this declarator to be a C++ destructor + /// setDestructor - Set this declarator to be a C++ destructor /// declarator. - void SetDestructor(Action::TypeTy *Ty, IdentifierInfo *ID, - SourceLocation Loc) { - Identifier = ID; + void setDestructor(Action::TypeTy *Ty, SourceLocation Loc) { IdentifierLoc = Loc; Kind = DK_Destructor; Type = Ty; } - // SetConversionFunction - Set this declarator to be a C++ + // setConversionFunction - Set this declarator to be a C++ // conversion function declarator. - void SetConversionFunction(Action::TypeTy *Ty, IdentifierInfo *ID, - SourceLocation Loc) { - Identifier = ID; + void setConversionFunction(Action::TypeTy *Ty, SourceLocation Loc) { + Identifier = 0; IdentifierLoc = Loc; Kind = DK_Conversion; Type = Ty; diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index dc4d6027ee..eee934bebb 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -67,12 +67,12 @@ ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC, FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, - IdentifierInfo *Id, QualType T, + DeclarationName N, QualType T, StorageClass S, bool isInline, ScopedDecl *PrevDecl, SourceLocation TypeSpecStartLoc) { void *Mem = C.getAllocator().Allocate<FunctionDecl>(); - return new (Mem) FunctionDecl(Function, DC, L, Id, T, S, isInline, PrevDecl, + return new (Mem) FunctionDecl(Function, DC, L, N, T, S, isInline, PrevDecl, TypeSpecStartLoc); } @@ -130,54 +130,6 @@ FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, } //===----------------------------------------------------------------------===// -// NamedDecl Implementation -//===----------------------------------------------------------------------===// - -std::string NamedDecl::getName() const { - switch (Name.getNameKind()) { - case DeclarationName::Identifier: - if (const IdentifierInfo *II = Name.getAsIdentifierInfo()) - return II->getName(); - return ""; - - case DeclarationName::ObjCZeroArgSelector: - case DeclarationName::ObjCOneArgSelector: - case DeclarationName::ObjCMultiArgSelector: - return Name.getObjCSelector().getName(); - - case DeclarationName::CXXConstructorName: { - QualType ClassType = Name.getCXXNameType(); - if (const RecordType *ClassRec = ClassType->getAsRecordType()) - return ClassRec->getDecl()->getName(); - return ClassType.getAsString(); - } - - case DeclarationName::CXXDestructorName: { - std::string Result = "~"; - QualType Type = Name.getCXXNameType(); - if (const RecordType *Rec = Type->getAsRecordType()) - Result += Rec->getDecl()->getName(); - else - Result += Type.getAsString(); - return Result; - } - - case DeclarationName::CXXConversionFunctionName: { - std::string Result = "operator "; - QualType Type = Name.getCXXNameType(); - if (const RecordType *Rec = Type->getAsRecordType()) - Result += Rec->getDecl()->getName(); - else - Result += Type.getAsString(); - return Result; - } - } - - assert(false && "Unexpected declaration name kind"); - return ""; -} - -//===----------------------------------------------------------------------===// // ScopedDecl Implementation //===----------------------------------------------------------------------===// diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 8855e99a26..4037404124 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -123,11 +123,12 @@ void CXXRecordDecl::addConversionFunction(ASTContext &Context, CXXMethodDecl * CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD, - SourceLocation L, IdentifierInfo *Id, + SourceLocation L, DeclarationName N, QualType T, bool isStatic, bool isInline, ScopedDecl *PrevDecl) { void *Mem = C.getAllocator().Allocate<CXXMethodDecl>(); - return new (Mem) CXXMethodDecl(CXXMethod, RD, L, Id, T, isStatic, isInline, PrevDecl); + return new (Mem) CXXMethodDecl(CXXMethod, RD, L, N, T, isStatic, isInline, + PrevDecl); } QualType CXXMethodDecl::getThisType(ASTContext &C) const { diff --git a/lib/AST/DeclarationName.cpp b/lib/AST/DeclarationName.cpp index 4266ef5eaf..d58016a44c 100644 --- a/lib/AST/DeclarationName.cpp +++ b/lib/AST/DeclarationName.cpp @@ -12,6 +12,8 @@ // //===----------------------------------------------------------------------===// #include "clang/AST/DeclarationName.h" +#include "clang/AST/Type.h" +#include "clang/AST/Decl.h" #include "clang/Basic/IdentifierTable.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/Bitcode/Serialize.h" @@ -94,6 +96,50 @@ DeclarationName::NameKind DeclarationName::getNameKind() const { return Identifier; } +std::string DeclarationName::getAsString() const { + switch (getNameKind()) { + case Identifier: + if (const IdentifierInfo *II = getAsIdentifierInfo()) + return II->getName(); + return ""; + + case ObjCZeroArgSelector: + case ObjCOneArgSelector: + case ObjCMultiArgSelector: + return getObjCSelector().getName(); + + case CXXConstructorName: { + QualType ClassType = getCXXNameType(); + if (const RecordType *ClassRec = ClassType->getAsRecordType()) + return ClassRec->getDecl()->getName(); + return ClassType.getAsString(); + } + + case CXXDestructorName: { + std::string Result = "~"; + QualType Type = getCXXNameType(); + if (const RecordType *Rec = Type->getAsRecordType()) + Result += Rec->getDecl()->getName(); + else + Result += Type.getAsString(); + return Result; + } + + case CXXConversionFunctionName: { + std::string Result = "operator "; + QualType Type = getCXXNameType(); + if (const RecordType *Rec = Type->getAsRecordType()) + Result += Rec->getDecl()->getName(); + else + Result += Type.getAsString(); + return Result; + } + } + + assert(false && "Unexpected declaration name kind"); + return ""; +} + QualType DeclarationName::getCXXNameType() const { if (CXXSpecialName *CXXName = getAsCXXSpecialName()) return CXXName->Type; diff --git a/lib/Basic/IdentifierTable.cpp b/lib/Basic/IdentifierTable.cpp index b83266d1ff..38bdb7e630 100644 --- a/lib/Basic/IdentifierTable.cpp +++ b/lib/Basic/IdentifierTable.cpp @@ -42,8 +42,7 @@ IdentifierInfo::IdentifierInfo() { IdentifierTable::IdentifierTable(const LangOptions &LangOpts) // Start with space for 8K identifiers. - : HashTable(8192), - ConstructorId(0), DestructorId(0), ConversionFunctionId(0) { + : HashTable(8192) { // Populate the identifier table with info about keywords for the current // language. @@ -53,32 +52,7 @@ IdentifierTable::IdentifierTable(const LangOptions &LangOpts) // This cstor is intended to be used only for serialization. IdentifierTable::IdentifierTable() - : HashTable(8192), - ConstructorId(0), DestructorId(0), ConversionFunctionId(0) { } - -/// getConstructorId - Return a placeholder identifier for a C++ -/// constructor. -IdentifierInfo &IdentifierTable::getConstructorId() { - if (!ConstructorId) - ConstructorId = &get("<constructor>"); - return *ConstructorId; -} - -/// getDestructorId - Return a placeholder identifier for a C++ -/// destructor. -IdentifierInfo &IdentifierTable::getDestructorId() { - if (!DestructorId) - DestructorId = &get("<destructor>"); - return *DestructorId; -} - -/// getConversionFunctionId - Return a placeholder identifier for a -/// C++ conversion function. -IdentifierInfo &IdentifierTable::getConversionFunctionId() { - if (!ConversionFunctionId) - ConversionFunctionId = &get("<conversion function>"); - return *ConversionFunctionId; -} + : HashTable(8192) { } //===----------------------------------------------------------------------===// // Language Keyword Implementation diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index baa510485a..048fafbe2d 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -1440,8 +1440,7 @@ void Parser::ParseDirectDeclarator(Declarator &D) { // a normal identifier. if (getLang().CPlusPlus && Actions.isCurrentClassName(*Tok.getIdentifierInfo(), CurScope)) - D.SetConstructor(Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope), - &PP.getIdentifierTable().getConstructorId(), + D.setConstructor(Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope), Tok.getLocation()); else D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation()); @@ -1452,8 +1451,7 @@ void Parser::ParseDirectDeclarator(Declarator &D) { SourceLocation TildeLoc = ConsumeToken(); if (Tok.is(tok::identifier)) { if (TypeTy *Type = ParseClassName()) - D.SetDestructor(Type, &PP.getIdentifierTable().getDestructorId(), - TildeLoc); + D.setDestructor(Type, TildeLoc); else D.SetIdentifier(0, TildeLoc); } else { @@ -1469,9 +1467,7 @@ void Parser::ParseDirectDeclarator(Declarator &D) { } else { // This must be a conversion function (C++ [class.conv.fct]). if (TypeTy *ConvType = ParseConversionFunctionId()) { - D.SetConversionFunction(ConvType, - &PP.getIdentifierTable().getConversionFunctionId(), - OperatorLoc); + D.setConversionFunction(ConvType, OperatorLoc); } } } else if (Tok.is(tok::l_paren) && SS.isEmpty()) { diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 752d552f11..48ced22723 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -454,7 +454,7 @@ Parser::DeclTy *Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) { // Parse the first declarator. ParseDeclarator(DeclaratorInfo); // Error parsing the declarator? - if (DeclaratorInfo.getIdentifier() == 0) { + if (!DeclaratorInfo.hasName()) { // If so, skip until the semi-colon or a }. SkipUntil(tok::r_brace, true); if (Tok.is(tok::semi)) diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index ee4cd7b554..3b36ebec7b 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -424,7 +424,7 @@ Parser::DeclTy *Parser::ParseDeclarationOrFunctionDefinition() { Declarator DeclaratorInfo(DS, Declarator::FileContext); ParseDeclarator(DeclaratorInfo); // Error parsing the declarator? - if (DeclaratorInfo.getIdentifier() == 0) { + if (!DeclaratorInfo.hasName()) { // If so, skip until the semi-colon or a }. SkipUntil(tok::r_brace, true); if (Tok.is(tok::semi)) diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 50a12f1385..771dc96463 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -272,7 +272,8 @@ public: QualType ConvertDeclSpecToType(const DeclSpec &DS); void ProcessTypeAttributeList(QualType &Result, const AttributeList *AL); QualType GetTypeForDeclarator(Declarator &D, Scope *S); - + DeclarationName GetNameForDeclarator(Declarator &D); + QualType ObjCGetTypeForMethodDefinition(DeclTy *D); bool UnwrapSimilarPointerTypes(QualType& T1, QualType& T2); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index ea2a3ad9a7..9c0a40e74a 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -754,14 +754,49 @@ bool Sema::CheckInitializerTypes(Expr *&Init, QualType &DeclType, return CheckInitList.HadError(); } +/// GetNameForDeclarator - Determine the full declaration name for the +/// given Declarator. +DeclarationName Sema::GetNameForDeclarator(Declarator &D) { + switch (D.getKind()) { + case Declarator::DK_Abstract: + assert(D.getIdentifier() == 0 && "abstract declarators have no name"); + return DeclarationName(); + + case Declarator::DK_Normal: + assert (D.getIdentifier() != 0 && "normal declarators have an identifier"); + return DeclarationName(D.getIdentifier()); + + case Declarator::DK_Constructor: { + QualType Ty = Context.getTypeDeclType((TypeDecl *)D.getDeclaratorIdType()); + Ty = Context.getCanonicalType(Ty); + return Context.DeclarationNames.getCXXConstructorName(Ty); + } + + case Declarator::DK_Destructor: { + QualType Ty = Context.getTypeDeclType((TypeDecl *)D.getDeclaratorIdType()); + Ty = Context.getCanonicalType(Ty); + return Context.DeclarationNames.getCXXDestructorName(Ty); + } + + case Declarator::DK_Conversion: { + QualType Ty = QualType::getFromOpaquePtr(D.getDeclaratorIdType()); + Ty = Context.getCanonicalType(Ty); + return Context.DeclarationNames.getCXXConversionFunctionName(Ty); + } + } + + assert(false && "Unknown name kind"); + return DeclarationName(); +} + Sema::DeclTy * Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { ScopedDecl *LastDeclarator = dyn_cast_or_null<ScopedDecl>((Decl *)lastDecl); - IdentifierInfo *II = D.getIdentifier(); - + DeclarationName Name = GetNameForDeclarator(D); + // All of these full declarators require an identifier. If it doesn't have // one, the ParsedFreeStandingDeclSpec action should be used. - if (II == 0) { + if (!Name) { if (!D.getInvalidType()) // Reject this if we think it is valid. Diag(D.getDeclSpec().getSourceRange().getBegin(), diag::err_declarator_need_ident, @@ -782,10 +817,10 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { // See if this is a redefinition of a variable in the same scope. if (!D.getCXXScopeSpec().isSet()) { DC = CurContext; - PrevDecl = LookupDecl(II, Decl::IDNS_Ordinary, S); + PrevDecl = LookupDecl(Name, Decl::IDNS_Ordinary, S); } else { // Something like "int foo::x;" DC = static_cast<DeclContext*>(D.getCXXScopeSpec().getScopeRep()); - PrevDecl = LookupDecl(II, Decl::IDNS_Ordinary, S, DC); + PrevDecl = LookupDecl(Name, Decl::IDNS_Ordinary, S, DC); // C++ 7.3.1.2p2: // Members (including explicit specializations of templates) of a named @@ -798,16 +833,17 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { if (PrevDecl == 0) { // No previous declaration in the qualifying scope. Diag(D.getIdentifierLoc(), diag::err_typecheck_no_member, - II->getName(), D.getCXXScopeSpec().getRange()); + Name.getAsString(), D.getCXXScopeSpec().getRange()); } else if (!CurContext->Encloses(DC)) { // The qualifying scope doesn't enclose the original declaration. // Emit diagnostic based on current scope. SourceLocation L = D.getIdentifierLoc(); SourceRange R = D.getCXXScopeSpec().getRange(); if (isa<FunctionDecl>(CurContext)) { - Diag(L, diag::err_invalid_declarator_in_function, II->getName(), R); + Diag(L, diag::err_invalid_declarator_in_function, Name.getAsString(), + R); } else { - Diag(L, diag::err_invalid_declarator_scope, II->getName(), + Diag(L, diag::err_invalid_declarator_scope, Name.getAsString(), cast<NamedDecl>(DC)->getName(), R); } } @@ -878,13 +914,9 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { bool isInvalidDecl = CheckConstructorDeclarator(D, R, SC); // Create the new declaration - QualType ClassType = Context.getTypeDeclType(cast<CXXRecordDecl>(DC)); - ClassType = Context.getCanonicalType(ClassType); - DeclarationName ConName - = Context.DeclarationNames.getCXXConstructorName(ClassType); NewFD = CXXConstructorDecl::Create(Context, cast<CXXRecordDecl>(DC), - D.getIdentifierLoc(), ConName, R, + D.getIdentifierLoc(), Name, R, isExplicit, isInline, /*isImplicitlyDeclared=*/false); @@ -895,14 +927,9 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { if (DC->isCXXRecord()) { bool isInvalidDecl = CheckDestructorDeclarator(D, R, SC); - QualType ClassType = Context.getTypeDeclType(cast<CXXRecordDecl>(DC)); - ClassType = Context.getCanonicalType(ClassType); - DeclarationName DesName - = Context.DeclarationNames.getCXXDestructorName(ClassType); - NewFD = CXXDestructorDecl::Create(Context, cast<CXXRecordDecl>(DC), - D.getIdentifierLoc(), DesName, R, + D.getIdentifierLoc(), Name, R, isInline, /*isImplicitlyDeclared=*/false); @@ -913,7 +940,7 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { // Create a FunctionDecl to satisfy the function definition parsing // code path. NewFD = FunctionDecl::Create(Context, DC, D.getIdentifierLoc(), - II, R, SC, isInline, LastDeclarator, + Name, R, SC, isInline, LastDeclarator, // FIXME: Move to DeclGroup... D.getDeclSpec().getSourceRange().getBegin()); NewFD->setInvalidDecl(); @@ -926,14 +953,9 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { } else { bool isInvalidDecl = CheckConversionDeclarator(D, R, SC); - QualType ConvType = R->getAsFunctionType()->getResultType(); - ConvType = Context.getCanonicalType(ConvType); - DeclarationName ConvName - = Context.DeclarationNames.getCXXConversionFunctionName(ConvType); - NewFD = CXXConversionDecl::Create(Context, cast<CXXRecordDecl>(DC), - D.getIdentifierLoc(), ConvName, R, + D.getIdentifierLoc(), Name, R, isInline, isExplicit); if (isInvalidDecl) @@ -942,13 +964,13 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { } else if (DC->isCXXRecord()) { // This is a C++ method declaration. NewFD = CXXMethodDecl::Create(Context, cast<CXXRecordDecl>(DC), - D.getIdentifierLoc(), II, R, + D.getIdentifierLoc(), Name, R, (SC == FunctionDecl::Static), isInline, LastDeclarator); } else { NewFD = FunctionDecl::Create(Context, DC, D.getIdentifierLoc(), - II, R, SC, isInline, LastDeclarator, + Name, R, SC, isInline, LastDeclarator, // FIXME: Move to DeclGroup... D.getDeclSpec().getSourceRange().getBegin()); } @@ -1128,6 +1150,14 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { Diag(D.getIdentifierLoc(), diag::err_mutable_nonmember); InvalidDecl = true; } + + IdentifierInfo *II = Name.getAsIdentifierInfo(); + if (!II) { + Diag(D.getIdentifierLoc(), diag::err_bad_variable_name, + Name.getAsString()); + return 0; + } + if (DC->isCXXRecord()) { assert(SC == VarDecl::Static && "Invalid storage class for member!"); // This is a static data member for a C++ class. @@ -1184,7 +1214,7 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { New->setLexicalDeclContext(CurContext); // If this has an identifier, add it to the scope stack. - if (II) + if (Name) PushOnScopeChains(New, S); // If any semantic error occurred, mark the decl as invalid. if (D.getInvalidType() || InvalidDecl) diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 2df6073e8b..f601fe4dc6 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -421,7 +421,7 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D, ExprTy *BW, ExprTy *InitExpr, DeclTy *LastInGroup) { const DeclSpec &DS = D.getDeclSpec(); - IdentifierInfo *II = D.getIdentifier(); + DeclarationName Name = GetNameForDeclarator(D); Expr *BitWidth = static_cast<Expr*>(BW); Expr *Init = static_cast<Expr*>(InitExpr); SourceLocation Loc = D.getIdentifierLoc(); @@ -499,7 +499,7 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D, if (!Member) return LastInGroup; - assert((II || isInstField) && "No identifier for non-field ?"); + assert((Name || isInstField) && "No identifier for non-field ?"); // set/getAccess is not part of Decl's interface to avoid bloating it with C++ // specific methods. Use a wrapper class that can be used with all C++ class @@ -532,14 +532,14 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D, // FIXME: Emit diagnostic about only constructors taking base initializers // or something similar, when constructor support is in place. Diag(Loc, diag::err_not_bitfield_type, - II->getName(), BitWidth->getSourceRange()); + Name.getAsString(), BitWidth->getSourceRange()); InvalidDecl = true; } else if (isInstField) { // C++ 9.6p3: A bit-field shall have integral or enumeration type. if (!cast<FieldDecl>(Member)->getType()->isIntegralType()) { Diag(Loc, diag::err_not_integral_type_bitfield, - II->getName(), BitWidth->getSourceRange()); + Name.getAsString(), BitWidth->getSourceRange()); InvalidDecl = true; } @@ -547,12 +547,12 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D, // A function typedef ("typedef int f(); f a;"). // C++ 9.6p3: A bit-field shall have integral or enumeration type. Diag(Loc, diag::err_not_integral_type_bitfield, - II->getName(), BitWidth->getSourceRange()); + Name.getAsString(), BitWidth->getSourceRange()); InvalidDecl = true; } else if (isa<TypedefDecl>(Member)) { // "cannot declare 'A' to be a bit-field type" - Diag(Loc, diag::err_not_bitfield_type, II->getName(), + Diag(Loc, diag::err_not_bitfield_type, Name.getAsString(), BitWidth->getSourceRange()); InvalidDecl = true; @@ -561,7 +561,7 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D, "Didn't we cover all member kinds?"); // C++ 9.6p3: A bit-field shall not be a static member. // "static member 'A' cannot be a bit-field" - Diag(Loc, diag::err_static_not_bitfield, II->getName(), + Diag(Loc, diag::err_static_not_bitfield, Name.getAsString(), BitWidth->getSourceRange()); InvalidDecl = true; } @@ -584,14 +584,14 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D, } else { // not const integral. Diag(Loc, diag::err_member_initialization, - II->getName(), Init->getSourceRange()); + Name.getAsString(), Init->getSourceRange()); InvalidDecl = true; } } else { // not static member. Diag(Loc, diag::err_member_initialization, - II->getName(), Init->getSourceRange()); + Name.getAsString(), Init->getSourceRange()); InvalidDecl = true; } } diff --git a/test/SemaCXX/conversion-function.cpp b/test/SemaCXX/conversion-function.cpp index 6450387b02..22ed411e64 100644 --- a/test/SemaCXX/conversion-function.cpp +++ b/test/SemaCXX/conversion-function.cpp @@ -15,6 +15,8 @@ public: operator int(); // expected-error{{conversion function must be a non-static member function}} +operator int; // expected-error{{'operator int' cannot be the name of a variable or data member}} + typedef int func_type(int); typedef int array_type[10]; diff --git a/test/SemaCXX/overloaded-operator-decl.cpp b/test/SemaCXX/overloaded-operator-decl.cpp index 8a042f68ef..7b05c38274 100644 --- a/test/SemaCXX/overloaded-operator-decl.cpp +++ b/test/SemaCXX/overloaded-operator-decl.cpp @@ -20,7 +20,8 @@ void f(X x) { x = operator+(x, x); } -X operator+(int, float); // expected-error{{overloaded 'operator+' must have at least one parameter of class or enumeration type}} +X operator+(int, float); // expected-error{{overloaded 'operator+' must have at least one parameter of class or enumeration type}} \ + // expected-error{{previous definition is here}} X operator*(X, X = 5); // expected-error{{parameter of overloaded 'operator*' cannot have a default argument}} @@ -35,3 +36,5 @@ typedef float FLOAT; Y& operator++(Y&); Y operator++(Y&, INT); X operator++(X&, FLOAT); // expected-error{{parameter of overloaded post-increment operator must have type 'int' (not 'float')}} + +int operator+; // expected-error{{redefinition of 'operator+' as different kind of symbol}} |