[cfe-commits] r59469 - in /cfe/trunk: include/clang/AST/ include/clang/Basic/ include/clang/Parse/ lib/AST/ lib/Basic/ lib/Parse/ lib/Sema/ test/SemaCXX/

Douglas Gregor doug.gregor at gmail.com
Mon Nov 17 14:58:35 PST 2008


Author: dgregor
Date: Mon Nov 17 16:58:34 2008
New Revision: 59469

URL: http://llvm.org/viewvc/llvm-project?rev=59469&view=rev
Log:
Eliminate all of the placeholder identifiers used for constructors,
destructors, and conversion functions. The placeholders were used to
work around the fact that the parser and some of Sema really wanted
declarators to have simple identifiers; now, the code that deals with
declarators will use DeclarationNames.


Modified:
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/include/clang/AST/DeclCXX.h
    cfe/trunk/include/clang/AST/DeclarationName.h
    cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/trunk/include/clang/Basic/IdentifierTable.h
    cfe/trunk/include/clang/Parse/DeclSpec.h
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/AST/DeclCXX.cpp
    cfe/trunk/lib/AST/DeclarationName.cpp
    cfe/trunk/lib/Basic/IdentifierTable.cpp
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp
    cfe/trunk/lib/Parse/Parser.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/test/SemaCXX/conversion-function.cpp
    cfe/trunk/test/SemaCXX/overloaded-operator-decl.cpp

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=59469&r1=59468&r2=59469&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Mon Nov 17 16:58:34 2008
@@ -100,7 +100,7 @@
   /// 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 @@
 
 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());  

Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=59469&r1=59468&r2=59469&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Mon Nov 17 16:58:34 2008
@@ -58,6 +58,11 @@
             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 @@
 
 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);
   

Modified: cfe/trunk/include/clang/AST/DeclarationName.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclarationName.h?rev=59469&r1=59468&r2=59469&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclarationName.h (original)
+++ cfe/trunk/include/clang/AST/DeclarationName.h Mon Nov 17 16:58:34 2008
@@ -164,6 +164,9 @@
   /// 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.

Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=59469&r1=59468&r2=59469&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Mon Nov 17 16:58:34 2008
@@ -660,6 +660,8 @@
      "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")

Modified: cfe/trunk/include/clang/Basic/IdentifierTable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/IdentifierTable.h?rev=59469&r1=59468&r2=59469&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/IdentifierTable.h (original)
+++ cfe/trunk/include/clang/Basic/IdentifierTable.h Mon Nov 17 16:58:34 2008
@@ -179,16 +179,6 @@
   /// 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 @@
     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;
   

Modified: cfe/trunk/include/clang/Parse/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/DeclSpec.h?rev=59469&r1=59468&r2=59469&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Parse/DeclSpec.h Mon Nov 17 16:58:34 2008
@@ -767,7 +767,12 @@
   /// 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 @@
       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;

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=59469&r1=59468&r2=59469&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Mon Nov 17 16:58:34 2008
@@ -67,12 +67,12 @@
 
 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 @@
 }
 
 //===----------------------------------------------------------------------===//
-// 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
 //===----------------------------------------------------------------------===//
 

Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=59469&r1=59468&r2=59469&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Mon Nov 17 16:58:34 2008
@@ -123,11 +123,12 @@
 
 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 {

Modified: cfe/trunk/lib/AST/DeclarationName.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclarationName.cpp?rev=59469&r1=59468&r2=59469&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclarationName.cpp (original)
+++ cfe/trunk/lib/AST/DeclarationName.cpp Mon Nov 17 16:58:34 2008
@@ -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 @@
   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;

Modified: cfe/trunk/lib/Basic/IdentifierTable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/IdentifierTable.cpp?rev=59469&r1=59468&r2=59469&view=diff

==============================================================================
--- cfe/trunk/lib/Basic/IdentifierTable.cpp (original)
+++ cfe/trunk/lib/Basic/IdentifierTable.cpp Mon Nov 17 16:58:34 2008
@@ -42,8 +42,7 @@
 
 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 @@
 
 // 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

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=59469&r1=59468&r2=59469&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Mon Nov 17 16:58:34 2008
@@ -1440,8 +1440,7 @@
     // 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 @@
     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 @@
     } 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()) {

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=59469&r1=59468&r2=59469&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Mon Nov 17 16:58:34 2008
@@ -454,7 +454,7 @@
     // 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))

Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=59469&r1=59468&r2=59469&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Mon Nov 17 16:58:34 2008
@@ -424,7 +424,7 @@
   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))

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=59469&r1=59468&r2=59469&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Mon Nov 17 16:58:34 2008
@@ -272,7 +272,8 @@
   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);

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=59469&r1=59468&r2=59469&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Nov 17 16:58:34 2008
@@ -754,14 +754,49 @@
   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 @@
   // 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 @@
     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 @@
       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 @@
       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 @@
         // 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 @@
       } 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 @@
     } 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 @@
       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 @@
   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)

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=59469&r1=59468&r2=59469&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Nov 17 16:58:34 2008
@@ -421,7 +421,7 @@
                                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 @@
 
   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 @@
       // 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 @@
       // 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 @@
              "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 @@
       } 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;
     }
   }

Modified: cfe/trunk/test/SemaCXX/conversion-function.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/conversion-function.cpp?rev=59469&r1=59468&r2=59469&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/conversion-function.cpp (original)
+++ cfe/trunk/test/SemaCXX/conversion-function.cpp Mon Nov 17 16:58:34 2008
@@ -15,6 +15,8 @@
 
 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];
 

Modified: cfe/trunk/test/SemaCXX/overloaded-operator-decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/overloaded-operator-decl.cpp?rev=59469&r1=59468&r2=59469&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/overloaded-operator-decl.cpp (original)
+++ cfe/trunk/test/SemaCXX/overloaded-operator-decl.cpp Mon Nov 17 16:58:34 2008
@@ -20,7 +20,8 @@
   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 @@
 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}}





More information about the cfe-commits mailing list