diff --git a/clang/Driver/RewriteBlocks.cpp b/clang/Driver/RewriteBlocks.cpp index d8e347fafbac..535915344c66 100644 --- a/clang/Driver/RewriteBlocks.cpp +++ b/clang/Driver/RewriteBlocks.cpp @@ -618,7 +618,7 @@ void RewriteBlocks::SynthesizeBlockLiterals(SourceLocation FunLocStart, void RewriteBlocks::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) { SourceLocation FunLocStart = FD->getTypeSpecStartLoc(); - const char *FuncName = FD->getName(); + const char *FuncName = FD->getIdentifierName(); SynthesizeBlockLiterals(FunLocStart, FuncName); } @@ -675,13 +675,13 @@ std::string RewriteBlocks::SynthesizeBlockCall(CallExpr *Exp) { const BlockPointerType *CPT = 0; if (const DeclRefExpr *DRE = dyn_cast(Exp->getCallee())) { - closureName = DRE->getDecl()->getName(); + closureName = DRE->getDecl()->getIdentifierName(); CPT = DRE->getType()->getAsBlockPointerType(); } else if (BlockDeclRefExpr *CDRE = dyn_cast(Exp->getCallee())) { - closureName = CDRE->getDecl()->getName(); + closureName = CDRE->getDecl()->getIdentifierName(); CPT = CDRE->getType()->getAsBlockPointerType(); } else if (MemberExpr *MExpr = dyn_cast(Exp->getCallee())) { - closureName = MExpr->getMemberDecl()->getName(); + closureName = MExpr->getMemberDecl()->getIdentifierName(); CPT = MExpr->getType()->getAsBlockPointerType(); } else { assert(1 && "RewriteBlockClass: Bad type"); @@ -1109,7 +1109,8 @@ void RewriteBlocks::HandleDeclInMainFile(Decl *D) { std::string Init = SynthesizeBlockInitExpr(CBE, VD); // Do the rewrite, using S.size() which contains the rewritten size. ReplaceText(CBE->getLocStart(), S.size(), Init.c_str(), Init.size()); - SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(), VD->getName()); + SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(), + VD->getIdentifierName()); } else if (CastExpr *CE = dyn_cast(VD->getInit())) { RewriteCastExpr(CE); } diff --git a/clang/Driver/RewriteObjC.cpp b/clang/Driver/RewriteObjC.cpp index 2903f998a05c..69aedcc2dd85 100644 --- a/clang/Driver/RewriteObjC.cpp +++ b/clang/Driver/RewriteObjC.cpp @@ -506,7 +506,7 @@ void RewriteObjC::HandleTopLevelDecl(Decl *D) { RewriteFunctionDecl(FD); } else if (VarDecl *FVD = dyn_cast(D)) { // declared in - if (strcmp(FVD->getName(), "_NSConstantStringClassReference") == 0) { + if (strcmp(FVD->getIdentifierName(), "_NSConstantStringClassReference") == 0) { ConstantStringClassReference = FVD; return; } @@ -1088,13 +1088,13 @@ Stmt *RewriteObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S, elementTypeAsString = ElementType.getAsString(); buf += elementTypeAsString; buf += " "; - elementName = D->getName(); + elementName = D->getIdentifierName(); buf += elementName; buf += ";\n\t"; } else { DeclRefExpr *DR = cast(S->getElement()); - elementName = DR->getDecl()->getName(); + elementName = DR->getDecl()->getIdentifierName(); elementTypeAsString = cast(DR->getDecl())->getType().getAsString(); } @@ -1694,7 +1694,7 @@ void RewriteObjC::SynthGetProtocolFunctionDecl() { void RewriteObjC::RewriteFunctionDecl(FunctionDecl *FD) { // declared in - if (strcmp(FD->getName(), "sel_registerName") == 0) { + if (strcmp(FD->getIdentifierName(), "sel_registerName") == 0) { SelGetUidFunctionDecl = FD; return; } @@ -2299,8 +2299,8 @@ Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) { // Create a call to objc_getProtocol("ProtocolName"). llvm::SmallVector ProtoExprs; QualType argType = Context->getPointerType(Context->CharTy); - ProtoExprs.push_back(new StringLiteral(Exp->getProtocol()->getName(), - strlen(Exp->getProtocol()->getName()), + ProtoExprs.push_back(new StringLiteral(Exp->getProtocol()->getIdentifierName(), + strlen(Exp->getProtocol()->getIdentifierName()), false, argType, SourceLocation(), SourceLocation())); CallExpr *ProtoExp = SynthesizeCallToFunctionDecl(GetProtocolFunctionDecl, @@ -2343,7 +2343,8 @@ bool RewriteObjC::BufferContainsPPDirectives(const char *startBuf, void RewriteObjC::SynthesizeObjCInternalStruct(ObjCInterfaceDecl *CDecl, std::string &Result) { assert(CDecl && "Class missing in SynthesizeObjCInternalStruct"); - assert(CDecl->getName() && "Name missing in SynthesizeObjCInternalStruct"); + assert(CDecl->getIdentifierName() && + "Name missing in SynthesizeObjCInternalStruct"); // Do not synthesize more than once. if (ObjCSynthesizedStructs.count(CDecl)) return; @@ -2922,15 +2923,15 @@ void RewriteObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl, // Build _objc_method_list for class's instance methods if needed RewriteObjCMethodsMetaData(IDecl->instmeth_begin(), IDecl->instmeth_end(), - true, "", IDecl->getName(), Result); + true, "", IDecl->getIdentifierName(), Result); // Build _objc_method_list for class's class methods if needed RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(), - false, "", IDecl->getName(), Result); + false, "", IDecl->getIdentifierName(), Result); // Protocols referenced in class declaration? RewriteObjCProtocolsMetaData(CDecl->getReferencedProtocols(), - "CLASS", CDecl->getName(), Result); + "CLASS", CDecl->getIdentifierName(), Result); // Declaration of class/meta-class metadata @@ -3429,7 +3430,7 @@ void RewriteObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart, void RewriteObjC::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) { SourceLocation FunLocStart = FD->getTypeSpecStartLoc(); - const char *FuncName = FD->getName(); + const char *FuncName = FD->getIdentifierName(); SynthesizeBlockLiterals(FunLocStart, FuncName); } @@ -3489,13 +3490,13 @@ Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp) { const BlockPointerType *CPT = 0; if (const DeclRefExpr *DRE = dyn_cast(Exp->getCallee())) { - closureName = DRE->getDecl()->getName(); + closureName = DRE->getDecl()->getIdentifierName(); CPT = DRE->getType()->getAsBlockPointerType(); } else if (BlockDeclRefExpr *CDRE = dyn_cast(Exp->getCallee())) { - closureName = CDRE->getDecl()->getName(); + closureName = CDRE->getDecl()->getIdentifierName(); CPT = CDRE->getType()->getAsBlockPointerType(); } else if (MemberExpr *MExpr = dyn_cast(Exp->getCallee())) { - closureName = MExpr->getMemberDecl()->getName(); + closureName = MExpr->getMemberDecl()->getIdentifierName(); CPT = MExpr->getType()->getAsBlockPointerType(); } else { assert(1 && "RewriteBlockClass: Bad type"); @@ -3812,15 +3813,15 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp) { E = BlockByCopyDecls.end(); I != E; ++I) { if (isObjCType((*I)->getType())) { // FIXME: Conform to ABI ([[obj retain] autorelease]). - FD = SynthBlockInitFunctionDecl((*I)->getName()); + FD = SynthBlockInitFunctionDecl((*I)->getIdentifierName()); Exp = new DeclRefExpr(FD, FD->getType(), SourceLocation()); } else if (isBlockPointerType((*I)->getType())) { - FD = SynthBlockInitFunctionDecl((*I)->getName()); + FD = SynthBlockInitFunctionDecl((*I)->getIdentifierName()); Arg = new DeclRefExpr(FD, FD->getType(), SourceLocation()); Exp = new CStyleCastExpr(Context->VoidPtrTy, Arg, Context->VoidPtrTy, SourceLocation(), SourceLocation()); } else { - FD = SynthBlockInitFunctionDecl((*I)->getName()); + FD = SynthBlockInitFunctionDecl((*I)->getIdentifierName()); Exp = new DeclRefExpr(FD, FD->getType(), SourceLocation()); } InitExprs.push_back(Exp); @@ -3828,7 +3829,7 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp) { // Output all "by ref" declarations. for (llvm::SmallPtrSet::iterator I = BlockByRefDecls.begin(), E = BlockByRefDecls.end(); I != E; ++I) { - FD = SynthBlockInitFunctionDecl((*I)->getName()); + FD = SynthBlockInitFunctionDecl((*I)->getIdentifierName()); Exp = new DeclRefExpr(FD, FD->getType(), SourceLocation()); Exp = new UnaryOperator(Exp, UnaryOperator::AddrOf, Context->getPointerType(Exp->getType()), @@ -4064,7 +4065,8 @@ void RewriteObjC::HandleDeclInMainFile(Decl *D) { if (VD->getInit()) { GlobalVarDecl = VD; RewriteFunctionBodyOrGlobalInitializer(VD->getInit()); - SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(), VD->getName()); + SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(), + VD->getIdentifierName()); GlobalVarDecl = 0; // This is needed for blocks. diff --git a/clang/docs/InternalsManual.html b/clang/docs/InternalsManual.html index 1e1fc990adc5..adfa7c3e7481 100644 --- a/clang/docs/InternalsManual.html +++ b/clang/docs/InternalsManual.html @@ -37,6 +37,7 @@ @@ -442,6 +443,107 @@ the low bit of the pointer to the Type object. This means that QualType is exactly the same size as a pointer, and this works fine on any system where malloc'd objects are at least 8 byte aligned.

+ +

Declaration names

+ + +

The DeclarationName class represents the name of a + declaration in Clang. Declarations in the C family of languages can + take several different forms. Most declarations are named by are + simple identifiers, e.g., "f" and "x" in + the function declaration f(int x). In C++, declaration + names can also name class constructors ("Class" + in struct Class { Class(); }), class destructors + ("~Class"), overloaded operator names ("operator+"), + and conversion functions ("operator void const *"). In + Objective-C, declaration names can refer to the names of Objective-C + methods, which involve the method name and the parameters, + collectively called a selector, e.g.., + "setWidth:height:". Since all of these kinds of + entities--variables, functions, Objective-C methods, C++ + constructors, destructors, and operators---are represented as + subclasses of Clang's common NamedDecl + class, DeclarationName is designed to efficiently + represent any kind of name.

+ +

Given + a DeclarationName N, N.getNameKind() + will produce a valid that describes what kind of name N + stores. There are 7 options (all of the names are inside + the DeclarationName class)

+
+
Identifier
+
The name is a simple + identifier. Use N.getAsIdentifierInfo() to retrieve the + corresponding IdentifierInfo* pointing to the actual + identifier. Note that C++ overloaded operators (e.g., + "operator+") are represented as special kinds of + identifiers. Use IdentifierInfo's getOverloadedOperatorID + function to determine whether an identifier is an overloaded + operator name.
+ +
ObjCZeroArgSelector, ObjCOneArgSelector, + ObjCMultiArgSelector
+
The name is an Objective-C selector, which can be retrieved as a + Selector instance + via N.getObjCSelector(). The three possible name + kinds for Objective-C reflect an optimization within + the DeclarationName class: both zero- and + one-argument selectors are stored as a + masked IdentifierInfo pointer, and therefore require + very little space, since zero- and one-argument selectors are far + more common than multi-argument selectors (which use a different + structure).
+ +
CXXConstructorName
+
The name is a C++ constructor + name. Use N.getCXXNameType() to retrieve + the type that this constructor is meant to + construct. The type is always the canonical type, since all + constructors for a given type have the same name.
+ +
CXXDestructorName
+
The name is a C++ destructor + name. Use N.getCXXNameType() to retrieve + the type whose destructor is being + named. This type is always a canonical type.
+ +
CXXConversionFunctionName
+
The name is a C++ conversion function. Conversion functions are + named according to the type they convert to, e.g., "operator void + const *". Use N.getCXXNameType() to retrieve + the type that this conversion function converts to. This type is + always a canonical type.
+
+ +

DeclarationNames are cheap to create, copy, and + compare. They require only a single pointer's worth of storage in + the common cases (identifiers, C++ overloaded operator names, zero- + and one-argument Objective-C selectors) and use dense, uniqued + storage for the other kinds of + names. Two DeclarationNames can be compared for + equality (==, !=) using a simple bitwise + comparison, can be ordered + with <, >, <=, + and >= (which provide a lexicographical ordering for + normal identifiers but an unspecified ordering for other kinds of + names), and can be placed into LLVM DenseMaps + and DenseSets.

+ +

DeclarationName instances can be created in different + ways depending on what kind of name the instance will store. Normal + identifiers (IdentifierInfo pointers), including + overloaded operator names, and Objective-C selectors + (Selector) can be implicitly converted + to DeclarationNames. Names for C++ constructors, + destructors, and conversion functions can be retrieved from + the DeclarationNameTable, an instance of which is + available as ASTContext::DeclarationNames. The member + functions getCXXConstructorName, getCXXDestructorName, + and getCXXConversionFunctionName, respectively, + return DeclarationName instances for the three kinds of + C++ special function names.

+

The CFG class

@@ -736,4 +838,4 @@ interacts with constant evaluation:

- \ No newline at end of file + diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index b5adffdcb0bc..46a4e6f53274 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -14,8 +14,10 @@ #ifndef LLVM_CLANG_AST_ASTCONTEXT_H #define LLVM_CLANG_AST_ASTCONTEXT_H +#include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LangOptions.h" #include "clang/AST/Builtins.h" +#include "clang/AST/DeclarationName.h" #include "clang/AST/DeclBase.h" #include "clang/AST/Type.h" #include "clang/Basic/SourceLocation.h" @@ -110,7 +112,8 @@ public: TargetInfo &Target; IdentifierTable &Idents; SelectorTable &Selectors; - + DeclarationNameTable DeclarationNames; + SourceManager& getSourceManager() { return SourceMgr; } llvm::MallocAllocator &getAllocator() { return Allocator; } const LangOptions& getLangOptions() const { return LangOpts; } diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 3a766bfd5ec2..2ac94a9bdfa4 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -14,7 +14,9 @@ #ifndef LLVM_CLANG_AST_DECL_H #define LLVM_CLANG_AST_DECL_H +#include "clang/Basic/IdentifierTable.h" #include "clang/Basic/OperatorKinds.h" +#include "clang/AST/DeclarationName.h" #include "clang/AST/DeclBase.h" #include "clang/Parse/AccessSpecifier.h" #include "llvm/ADT/SmallVector.h" @@ -24,7 +26,6 @@ class Expr; class Stmt; class CompoundStmt; class StringLiteral; -class IdentifierInfo; /// TranslationUnitDecl - The top declaration context. /// FIXME: The TranslationUnit class should probably be modified to serve as @@ -56,19 +57,51 @@ protected: friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C); }; -/// NamedDecl - This represents a decl with an identifier for a name. Many +/// NamedDecl - This represents a decl with a name. Many /// decls have names, but not ObjCMethodDecl, @class, etc. class NamedDecl : public Decl { - /// Identifier - The identifier for this declaration (e.g. the name for the - /// variable, the tag for a struct). - IdentifierInfo *Identifier; + /// Name - The name of this declaration, which is typically a normal + /// identifier but may also be a special kind of name (C++ + /// constructor, Objective-C selector, etc.) + DeclarationName Name; + +protected: + NamedDecl(Kind DK, SourceLocation L, DeclarationName N) + : Decl(DK, L), Name(N) {} + public: NamedDecl(Kind DK, SourceLocation L, IdentifierInfo *Id) - : Decl(DK, L), Identifier(Id) {} + : Decl(DK, L), Name(Id) {} + + /// getIdentifier - Get the identifier that names this declaration, + /// if there is one. This will return NULL if this declaration has + /// no name (e.g., for an unnamed class) or if the name is a special + /// name (C++ constructor, Objective-C selector, etc.). + IdentifierInfo *getIdentifier() const { return Name.getAsIdentifierInfo(); } + + /// getIdentifierName - Get the name of identifier for this + /// declaration as a string. If the declaration has no name, or if + /// the name is a special name (C++ constructor, Objective-C + /// selector, etc.), returns NULL. + const char *getIdentifierName() const { + if (IdentifierInfo *II = getIdentifier()) + return II->getName(); + else + return 0; + } + + /// getDeclName - Get the actual, stored name of the declaration, + /// which may be a special name. + DeclarationName getDeclName() const { return Name; } + + /// getName - Get a human-readable name for the declaration, even if + /// it is one of the special kinds of names (C++ constructor, + /// Objective-C selector, etc.). Creating this name requires some + /// expensive string manipulation, so it should be called only when + /// absolutely critical. For simple declarations, @c + /// getIdentifierName() should suffice. + std::string getName() const; - IdentifierInfo *getIdentifier() const { return Identifier; } - virtual const char *getName() const; - static bool classof(const Decl *D) { return D->getKind() >= NamedFirst && D->getKind() <= NamedLast; } @@ -120,8 +153,8 @@ class ScopedDecl : public NamedDecl { protected: ScopedDecl(Kind DK, DeclContext *DC, SourceLocation L, - IdentifierInfo *Id, ScopedDecl *PrevDecl) - : NamedDecl(DK, L, Id), NextDeclarator(PrevDecl), Next(0), + DeclarationName N, ScopedDecl *PrevDecl) + : NamedDecl(DK, L, N), NextDeclarator(PrevDecl), Next(0), DeclCtx(reinterpret_cast(DC)) {} virtual ~ScopedDecl(); @@ -272,8 +305,8 @@ class ValueDecl : public ScopedDecl { protected: ValueDecl(Kind DK, DeclContext *DC, SourceLocation L, - IdentifierInfo *Id, QualType T, ScopedDecl *PrevDecl) - : ScopedDecl(DK, DC, L, Id, PrevDecl), DeclType(T) {} + DeclarationName N, QualType T, ScopedDecl *PrevDecl) + : ScopedDecl(DK, DC, L, N, PrevDecl), DeclType(T) {} public: QualType getType() const { return DeclType; } void setType(QualType newType) { DeclType = newType; } @@ -512,10 +545,10 @@ private: SourceLocation TypeSpecStartLoc; protected: FunctionDecl(Kind DK, DeclContext *DC, SourceLocation L, - IdentifierInfo *Id, QualType T, + DeclarationName N, QualType T, StorageClass S, bool isInline, ScopedDecl *PrevDecl, SourceLocation TSSL = SourceLocation()) - : ValueDecl(DK, DC, L, Id, T, PrevDecl), + : ValueDecl(DK, DC, L, N, T, PrevDecl), DeclContext(DK), ParamInfo(0), Body(0), PreviousDeclaration(0), SClass(S), IsInline(isInline), IsImplicit(0), TypeSpecStartLoc(TSSL) {} diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index f0ac1a5335ea..753d572fb3a6 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -52,6 +52,7 @@ public: ObjCCategory, ObjCCategoryImpl, ObjCImplementation, + ObjCMethod, // [DeclContext] ObjCProtocol, ObjCProperty, // ScopedDecl @@ -75,7 +76,6 @@ public: ParmVar, ObjCInterface, // [DeclContext] ObjCCompatibleAlias, - ObjCMethod, // [DeclContext] ObjCClass, ObjCForwardProtocol, ObjCPropertyImpl, diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index 39c22aaf70d6..8edfc650a4ab 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -34,8 +34,8 @@ class CXXConversionDecl; /// overloaded functions for name lookup. class OverloadedFunctionDecl : public NamedDecl { protected: - OverloadedFunctionDecl(DeclContext *DC, IdentifierInfo *Id) - : NamedDecl(OverloadedFunction, SourceLocation(), Id) { } + OverloadedFunctionDecl(DeclContext *DC, DeclarationName N) + : NamedDecl(OverloadedFunction, SourceLocation(), N) { } /// Functions - the set of overloaded functions contained in this /// overload set. @@ -47,16 +47,16 @@ public: function_const_iterator; static OverloadedFunctionDecl *Create(ASTContext &C, DeclContext *DC, - IdentifierInfo *Id); + DeclarationName N); /// addOverload - Add an overloaded function FD to this set of /// overloaded functions. void addOverload(FunctionDecl *FD) { assert((!getNumFunctions() || (FD->getDeclContext() == getDeclContext())) && "Overloaded functions must all be in the same context"); - assert((FD->getIdentifier() == getIdentifier() || - isa(FD)) && - "Overloaded functions must have the same name or be conversions."); + assert((FD->getDeclName() == getDeclName() || + isa(FD) || isa(FD)) && + "Overloaded functions must have the same name"); Functions.push_back(FD); } @@ -246,7 +246,7 @@ class CXXRecordDecl : public RecordDecl, public DeclContext { /// CXXConversionDecl. OverloadedFunctionDecl Conversions; - CXXRecordDecl(ASTContext &C, TagKind TK, DeclContext *DC, + CXXRecordDecl(TagKind TK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id); ~CXXRecordDecl(); @@ -389,9 +389,9 @@ protected: class CXXMethodDecl : public FunctionDecl { protected: CXXMethodDecl(Kind DK, CXXRecordDecl *RD, SourceLocation L, - IdentifierInfo *Id, QualType T, + DeclarationName N, QualType T, bool isStatic, bool isInline, ScopedDecl *PrevDecl) - : FunctionDecl(DK, RD, L, Id, T, (isStatic ? Static : None), + : FunctionDecl(DK, RD, L, N, T, (isStatic ? Static : None), isInline, PrevDecl) {} public: @@ -576,21 +576,19 @@ class CXXConstructorDecl : public CXXMethodDecl { /// FIXME: Add support for base and member initializers. CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation L, - IdentifierInfo *Id, QualType T, + DeclarationName N, QualType T, bool isExplicit, bool isInline, bool isImplicitlyDeclared) - : CXXMethodDecl(CXXConstructor, RD, L, Id, T, false, isInline, /*PrevDecl=*/0), + : CXXMethodDecl(CXXConstructor, RD, L, N, T, false, isInline, + /*PrevDecl=*/0), Explicit(isExplicit), ImplicitlyDeclared(isImplicitlyDeclared), ImplicitlyDefined(false) { } public: static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD, - SourceLocation L, IdentifierInfo *Id, + SourceLocation L, DeclarationName N, QualType T, bool isExplicit, bool isInline, bool isImplicitlyDeclared); - /// getName - Returns a human-readable name for this constructor. - virtual const char *getName() const; - /// isExplicit - Whether this constructor was marked "explicit" or not. bool isExplicit() const { return Explicit; } @@ -686,29 +684,20 @@ class CXXDestructorDecl : public CXXMethodDecl { /// @c !ImplicitlyDeclared && ImplicitlyDefined. bool ImplicitlyDefined : 1; - /// Name - The formatted name of this destructor. This will be - /// generated when getName() is called. - mutable char *Name; - CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation L, - IdentifierInfo *Id, QualType T, + DeclarationName N, QualType T, bool isInline, bool isImplicitlyDeclared) - : CXXMethodDecl(CXXDestructor, RD, L, Id, T, false, isInline, + : CXXMethodDecl(CXXDestructor, RD, L, N, T, false, isInline, /*PrevDecl=*/0), ImplicitlyDeclared(isImplicitlyDeclared), - ImplicitlyDefined(false), Name(0) { } + ImplicitlyDefined(false) { } public: static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD, - SourceLocation L, IdentifierInfo *Id, + SourceLocation L, DeclarationName N, QualType T, bool isInline, bool isImplicitlyDeclared); - virtual ~CXXDestructorDecl(); - - /// getName - Returns a human-readable name for this destructor. - virtual const char *getName() const; - /// isImplicitlyDeclared - Whether this destructor was implicitly /// declared. If false, then this destructor was explicitly /// declared by the user. @@ -762,29 +751,19 @@ class CXXConversionDecl : public CXXMethodDecl { /// explicitly wrote a cast. This is a C++0x feature. bool Explicit : 1; - /// Name - The formatted name of this conversion function. This will - /// be generated when getName() is called. - mutable char *Name; - CXXConversionDecl(CXXRecordDecl *RD, SourceLocation L, - IdentifierInfo *Id, QualType T, + DeclarationName N, QualType T, bool isInline, bool isExplicit) - : CXXMethodDecl(CXXConversion, RD, L, Id, T, false, isInline, + : CXXMethodDecl(CXXConversion, RD, L, N, T, false, isInline, /*PrevDecl=*/0), - Explicit(isExplicit), Name(0) { } + Explicit(isExplicit) { } public: static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD, - SourceLocation L, IdentifierInfo *Id, + SourceLocation L, DeclarationName N, QualType T, bool isInline, bool isExplicit); - virtual ~CXXConversionDecl(); - - /// getName - Returns a human-readable name for this conversion - /// function. - virtual const char *getName() const; - /// isExplicit - Whether this is an explicit conversion operator /// (C++0x only). Explicit conversion operators are only considered /// when the user has explicitly written a cast. diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h index e8c383d73e45..ffbb1e56fb83 100644 --- a/clang/include/clang/AST/DeclObjC.h +++ b/clang/include/clang/AST/DeclObjC.h @@ -91,7 +91,7 @@ public: /// A selector represents a unique name for a method. The selector names for /// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu. /// -class ObjCMethodDecl : public Decl, public DeclContext { +class ObjCMethodDecl : public NamedDecl, public DeclContext { public: enum ImplementationControl { None, Required, Optional }; private: @@ -115,9 +115,6 @@ private: // Context this method is declared in. NamedDecl *MethodContext; - // A unigue name for this method. - Selector SelName; - // Type of this method. QualType MethodDeclType; /// ParamInfo - new[]'d array of pointers to VarDecls for the formal @@ -146,13 +143,13 @@ private: bool isVariadic = false, bool isSynthesized = false, ImplementationControl impControl = None) - : Decl(ObjCMethod, beginLoc), + : NamedDecl(ObjCMethod, beginLoc, SelInfo), DeclContext(ObjCMethod), IsInstance(isInstance), IsVariadic(isVariadic), IsSynthesized(isSynthesized), DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None), MethodContext(static_cast(contextDecl)), - SelName(SelInfo), MethodDeclType(T), + MethodDeclType(T), ParamInfo(0), NumMethodParams(0), EndLoc(endLoc), Body(0), SelfDecl(0), CmdDecl(0) {} @@ -191,7 +188,7 @@ public: return const_cast(this)->getClassInterface(); } - Selector getSelector() const { return SelName; } + Selector getSelector() const { return getDeclName().getObjCSelector(); } unsigned getSynthesizedMethodSize() const; QualType getResultType() const { return MethodDeclType; } diff --git a/clang/include/clang/AST/DeclarationName.h b/clang/include/clang/AST/DeclarationName.h new file mode 100644 index 000000000000..385e2f34a342 --- /dev/null +++ b/clang/include/clang/AST/DeclarationName.h @@ -0,0 +1,294 @@ +//===-- DeclarationName.h - Representation of declaration names -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the DeclarationName and DeclarationNameTable classes. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_AST_DECLARATIONNAME_H +#define LLVM_CLANG_AST_DECLARATIONNAME_H + +#include "clang/Basic/IdentifierTable.h" +#include "clang/AST/Type.h" +#include "llvm/Bitcode/SerializationFwd.h" + +namespace llvm { + template struct DenseMapInfo; +} + +namespace clang { + class CXXSpecialName; // a private class used by DeclarationName + class DeclarationNameExtra; // a private class used by DeclarationName + class IdentifierInfo; + class MultiKeywordSelector; // a private class used by Selector and DeclarationName + +/// DeclarationName - The name of a declaration. In the common case, +/// this just stores an IdentifierInfo pointer to a normal +/// name. However, it also provides encodings for Objective-C +/// selectors (optimizing zero- and one-argument selectors, which make +/// up 78% percent of all selectors in Cocoa.h) and special C++ names +/// for constructors, destructors, and conversion functions. +class DeclarationName { +public: + /// NameKind - The kind of name this object contains. + enum NameKind { + Identifier, + ObjCZeroArgSelector, + ObjCOneArgSelector, + ObjCMultiArgSelector, + CXXConstructorName, + CXXDestructorName, + CXXConversionFunctionName + }; + +private: + /// StoredNameKind - The kind of name that is actually stored in the + /// upper bits of the Ptr field. This is only used internally. + enum StoredNameKind { + StoredIdentifier = 0, + StoredObjCZeroArgSelector, + StoredObjCOneArgSelector, + StoredObjCMultiArgSelectorOrCXXName, + PtrMask = 0x03 + }; + + /// Ptr - The lowest two bits are used to express what kind of name + /// we're actually storing, using the values of NameKind. Depending + /// on the kind of name this is, the upper bits of Ptr may have one + /// of several different meanings: + /// + /// Identifier - The name is a normal identifier, and Ptr is a + /// normal IdentifierInfo pointer. + /// + /// ObjCZeroArgSelector - The name is an Objective-C selector with + /// zero arguments, and Ptr is an IdentifierInfo pointer pointing + /// to the selector name. + /// + /// ObjCOneArgSelector - The name is an Objective-C selector with + /// one argument, and Ptr is an IdentifierInfo pointer pointing to + /// the selector name. + /// + /// ObjCMultiArgSelectorOrCXXName - This is either an Objective-C + /// selector with two or more arguments or it is a C++ name. Ptr + /// is actually a DeclarationNameExtra structure, whose first + /// value will tell us whether this is an Objective-C selector or + /// special C++ name. + uintptr_t Ptr; + + /// getStoredNameKind - Return the kind of object that is stored in + /// Ptr. + StoredNameKind getStoredNameKind() const { + return static_cast(Ptr & PtrMask); + } + + /// getExtra - Get the "extra" information associated with this + /// multi-argument selector or C++ special name. + DeclarationNameExtra *getExtra() const { + assert(getStoredNameKind() == StoredObjCMultiArgSelectorOrCXXName && + "Declaration name does not store an Extra structure"); + return reinterpret_cast(Ptr & ~PtrMask); + } + + /// getAsCXXSpecialName - If the stored pointer is actually a + /// CXXSpecialName, returns a pointer to it. Otherwise, returns + /// a NULL pointer. + CXXSpecialName *getAsCXXSpecialName() const { + if (getNameKind() >= CXXConstructorName && + getNameKind() <= CXXConversionFunctionName) + return reinterpret_cast(Ptr & ~PtrMask); + else + return 0; + } + + // Construct a declaration name from the name of a C++ constructor, + // destructor, or conversion function. + DeclarationName(CXXSpecialName *Name) + : Ptr(reinterpret_cast(Name)) { + assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXSpecialName"); + Ptr |= StoredObjCMultiArgSelectorOrCXXName; + } + + // Construct a declaration name from a zero- or one-argument + // Objective-C selector. + DeclarationName(IdentifierInfo *II, unsigned numArgs) + : Ptr(reinterpret_cast(II)) { + assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo"); + assert(numArgs < 2 && "Use MultiKeywordSelector for >= 2 arguments"); + if (numArgs == 0) + Ptr |= StoredObjCZeroArgSelector; + else + Ptr |= StoredObjCOneArgSelector; + } + + // Construct a declaration name from an Objective-C multiple-keyword + // selector. + DeclarationName(MultiKeywordSelector *SI) + : Ptr(reinterpret_cast(SI)) { + assert((Ptr & PtrMask) == 0 && "Improperly aligned MultiKeywordSelector"); + Ptr |= StoredObjCMultiArgSelectorOrCXXName; + } + + /// Construct a declaration name from a raw pointer. + DeclarationName(uintptr_t Ptr) : Ptr(Ptr) { } + + friend class DeclarationNameTable; + +public: + /// DeclarationName - Used to create an empty selector. + DeclarationName() : Ptr(0) { } + + // Construct a declaration name from an IdentifierInfo *. + DeclarationName(IdentifierInfo *II) : Ptr(reinterpret_cast(II)) { + assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo"); + } + + // Construct a declaration name from an Objective-C selector. + DeclarationName(Selector Sel); + + /// getNameKind - Determine what kind of name this is. + NameKind getNameKind() const; + + /// getAsIdentifierInfo - Retrieve the IdentifierInfo * stored in + /// this declaration name, or NULL if this declaration name isn't a + /// simple identifier. + IdentifierInfo *getAsIdentifierInfo() const { + if (getNameKind() == Identifier) + return reinterpret_cast(Ptr); + else + return 0; + } + + /// getAsOpaqueInteger - Get the representation of this declaration + /// name as an opaque integer. + uintptr_t getAsOpaqueInteger() const { return Ptr; } + + /// getCXXNameType - If this name is one of the C++ names (of a + /// constructor, destructor, or conversion function), return the + /// type associated with that name. + QualType getCXXNameType() const; + + /// getObjCSelector - Get the Objective-C selector stored in this + /// declaration name. + Selector getObjCSelector() const; + + /// operator== - Determine whether the specified names are identical.. + friend bool operator==(DeclarationName LHS, DeclarationName RHS) { + return LHS.Ptr == RHS.Ptr; + } + + /// operator!= - Determine whether the specified names are different. + friend bool operator!=(DeclarationName LHS, DeclarationName RHS) { + return LHS.Ptr != RHS.Ptr; + } + + static DeclarationName getEmptyMarker() { + return DeclarationName(uintptr_t(-1)); + } + + static DeclarationName getTombstoneMarker() { + return DeclarationName(uintptr_t(-2)); + } +}; + +/// Ordering on two declaration names. If both names are identifiers, +/// this provides a lexicographical ordering. +bool operator<(DeclarationName LHS, DeclarationName RHS); + +/// Ordering on two declaration names. If both names are identifiers, +/// this provides a lexicographical ordering. +inline bool operator>(DeclarationName LHS, DeclarationName RHS) { + return RHS < LHS; +} + +/// Ordering on two declaration names. If both names are identifiers, +/// this provides a lexicographical ordering. +inline bool operator<=(DeclarationName LHS, DeclarationName RHS) { + return !(RHS < LHS); +} + +/// Ordering on two declaration names. If both names are identifiers, +/// this provides a lexicographical ordering. +inline bool operator>=(DeclarationName LHS, DeclarationName RHS) { + return !(LHS < RHS); +} + +/// DeclarationNameTable - Used to store and retrieve DeclarationName +/// instances for the various kinds of declaration names, e.g., normal +/// identifiers, C++ constructor names, etc. This class contains +/// uniqued versions of each of the C++ special names, which can be +/// retrieved using its member functions (e.g., +/// getCXXConstructorName). +class DeclarationNameTable { + void *CXXSpecialNamesImpl; // Actually a FoldingSet * + + DeclarationNameTable(const DeclarationNameTable&); // NONCOPYABLE + DeclarationNameTable& operator=(const DeclarationNameTable&); // NONCOPYABLE + +public: + DeclarationNameTable(); + ~DeclarationNameTable(); + + /// getIdentifier - Create a declaration name that is a simple + /// identifier. + DeclarationName getIdentifier(IdentifierInfo *ID) { + return DeclarationName(ID); + } + + /// getCXXConstructorName - Returns the name of a C++ constructor + /// for the given Type. + DeclarationName getCXXConstructorName(QualType Ty) { + return getCXXSpecialName(DeclarationName::CXXConstructorName, Ty); + } + + /// getCXXDestructorName - Returns the name of a C++ destructor + /// for the given Type. + DeclarationName getCXXDestructorName(QualType Ty) { + return getCXXSpecialName(DeclarationName::CXXDestructorName, Ty); + } + + /// getCXXConversionFunctionName - Returns the name of a C++ + /// conversion function for the given Type. + DeclarationName getCXXConversionFunctionName(QualType Ty) { + return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty); + } + + /// getCXXSpecialName - Returns a declaration name for special kind + /// of C++ name, e.g., for a constructor, destructor, or conversion + /// function. + DeclarationName getCXXSpecialName(DeclarationName::NameKind Kind, + QualType Ty); +}; + +} // end namespace clang + +namespace llvm { +/// Define DenseMapInfo so that DeclarationNames can be used as keys +/// in DenseMap and DenseSets. +template<> +struct DenseMapInfo { + static inline clang::DeclarationName getEmptyKey() { + return clang::DeclarationName::getEmptyMarker(); + } + + static inline clang::DeclarationName getTombstoneKey() { + return clang::DeclarationName::getTombstoneMarker(); + } + + static unsigned getHashValue(clang::DeclarationName); + + static inline bool + isEqual(clang::DeclarationName LHS, clang::DeclarationName RHS) { + return LHS == RHS; + } + + static inline bool isPod() { return true; } +}; + +} // end namespace llvm + +#endif diff --git a/clang/include/clang/Basic/IdentifierTable.h b/clang/include/clang/Basic/IdentifierTable.h index f6b95ba380cf..a13d4ba538c1 100644 --- a/clang/include/clang/Basic/IdentifierTable.h +++ b/clang/include/clang/Basic/IdentifierTable.h @@ -29,10 +29,11 @@ namespace llvm { namespace clang { struct LangOptions; - class MultiKeywordSelector; // a private class used by Selector. class IdentifierInfo; class SourceLocation; - + class MultiKeywordSelector; // private class used by Selector + class DeclarationName; // AST class that stores declaration names + /// IdentifierLocPair - A simple pair of identifier info and location. typedef std::pair IdentifierLocPair; @@ -281,8 +282,9 @@ class Selector { } Selector(uintptr_t V) : InfoPtr(V) {} public: - friend class SelectorTable; // only the SelectorTable can create these. - + friend class SelectorTable; // only the SelectorTable can create these + friend class DeclarationName; // and the AST's DeclarationName. + /// The default ctor should only be used when creating data structures that /// will contain selectors. Selector() : InfoPtr(0) {} @@ -362,12 +364,35 @@ public: static SelectorTable* CreateAndRegister(llvm::Deserializer& D); }; +/// DeclarationNameExtra - Common base of the MultiKeywordSelector and +/// CXXSpecialName classes, both of which are private classes that can +/// be stored by the AST's DeclarationName class. +class DeclarationNameExtra { +public: + /// ExtraKind - The kind of "extra" information stored in the + /// DeclarationName. See @c ExtraKindOrNumArgs for an explanation of + /// how these enumerator values are used. + enum ExtraKind { + CXXConstructor = 0, + CXXDestructor, + CXXConversionFunction, + NUM_EXTRA_KINDS + }; + + /// ExtraKindOrNumArgs - Either the kind of C++ special name (if the + /// value is one of the CXX* enumerators of ExtraKind), in which + /// case the DeclarationNameExtra is also a CXXSpecialName, or + /// NUM_EXTRA_KINDS+NumArgs, where NumArgs is the number of + /// arguments in the Objective-C selector, in which case the + /// DeclarationNameExtra is also a MultiKeywordSelector. + unsigned ExtraKindOrNumArgs; +}; + } // end namespace clang - +namespace llvm { /// Define DenseMapInfo so that Selectors can be used as keys in DenseMap and /// DenseSets. -namespace llvm { template <> struct DenseMapInfo { static inline clang::Selector getEmptyKey() { @@ -385,6 +410,6 @@ struct DenseMapInfo { static bool isPod() { return true; } }; -} // end namespace llvm +} // end namespace llvm #endif diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 47ada4fe1a2a..e8bd3ac6d6cd 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -87,7 +87,7 @@ class Preprocessor { /// FIXME: Make sure the lifetime of Identifiers/Selectors *isn't* tied to /// the lifetime fo the preprocessor. SelectorTable Selectors; - + /// PragmaHandlers - This tracks all of the pragmas that the client registered /// with this preprocessor. PragmaNamespace *PragmaHandlers; @@ -175,7 +175,7 @@ public: IdentifierTable &getIdentifierTable() { return Identifiers; } SelectorTable &getSelectorTable() { return Selectors; } - + inline FullSourceLoc getFullLoc(SourceLocation Loc) const { return FullSourceLoc(Loc, getSourceManager()); } diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index e84cc4b3078a..ee57816da3fd 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -33,7 +33,7 @@ ASTContext::ASTContext(const LangOptions& LOpts, SourceManager &SM, unsigned size_reserve) : CFConstantStringTypeDecl(0), ObjCFastEnumerationStateTypeDecl(0), SourceMgr(SM), LangOpts(LOpts), Target(t), - Idents(idents), Selectors(sels) + Idents(idents), Selectors(sels) { if (size_reserve > 0) Types.reserve(size_reserve); InitBuiltinTypes(); @@ -996,7 +996,7 @@ QualType ASTContext::getObjCInterfaceType(ObjCInterfaceDecl *Decl) { /// alphabetically. static bool CmpProtocolNames(const ObjCProtocolDecl *LHS, const ObjCProtocolDecl *RHS) { - return strcmp(LHS->getName(), RHS->getName()) < 0; + return LHS->getDeclName() < RHS->getDeclName(); } static void SortAndUniqueProtocols(ObjCProtocolDecl **&Protocols, @@ -1449,7 +1449,7 @@ QualType ASTContext::getObjCFastEnumerationStateType() // typedef BOOL; static bool isTypeTypedefedAsBOOL(QualType T) { if (const TypedefType *TT = dyn_cast(T)) - return !strcmp(TT->getDecl()->getName(), "BOOL"); + return !strcmp(TT->getDecl()->getIdentifierName(), "BOOL"); return false; } @@ -2260,7 +2260,8 @@ ASTContext* ASTContext::Create(llvm::Deserializer& D) { unsigned size_reserve = D.ReadInt(); - ASTContext* A = new ASTContext(LOpts, SM, t, idents, sels, size_reserve); + ASTContext* A = new ASTContext(LOpts, SM, t, idents, sels, + size_reserve); for (unsigned i = 0; i < size_reserve; ++i) Type::Create(*A,i,D); diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt index a58b3b162fbe..4ac6a6e98e4b 100644 --- a/clang/lib/AST/CMakeLists.txt +++ b/clang/lib/AST/CMakeLists.txt @@ -5,6 +5,7 @@ add_clang_library(clangAST ASTContext.cpp Builtins.cpp CFG.cpp + DeclarationName.cpp DeclBase.cpp Decl.cpp DeclCXX.cpp diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index fa5e9ce36ebe..dc4d6027ee8b 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -133,9 +133,47 @@ FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, // NamedDecl Implementation //===----------------------------------------------------------------------===// -const char *NamedDecl::getName() const { - if (const IdentifierInfo *II = getIdentifier()) - return II->getName(); +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 ""; } diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 1de640743d9f..8855e99a26f2 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -27,20 +27,20 @@ CXXFieldDecl *CXXFieldDecl::Create(ASTContext &C, CXXRecordDecl *RD, return new (Mem) CXXFieldDecl(RD, L, Id, T, BW); } -CXXRecordDecl::CXXRecordDecl(ASTContext &C, TagKind TK, DeclContext *DC, +CXXRecordDecl::CXXRecordDecl(TagKind TK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id) : RecordDecl(CXXRecord, TK, DC, L, Id), DeclContext(CXXRecord), UserDeclaredConstructor(false), UserDeclaredCopyConstructor(false), Aggregate(true), Polymorphic(false), Bases(0), NumBases(0), - Constructors(DC, &C.Idents.getConstructorId()), + Constructors(DC, DeclarationName()), Destructor(0), - Conversions(DC, &C.Idents.getConversionFunctionId()) { } + Conversions(DC, DeclarationName()) { } CXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, CXXRecordDecl* PrevDecl) { void *Mem = C.getAllocator().Allocate(); - CXXRecordDecl* R = new (Mem) CXXRecordDecl(C, TK, DC, L, Id); + CXXRecordDecl* R = new (Mem) CXXRecordDecl(TK, DC, L, Id); C.getTypeDeclType(R, PrevDecl); return R; } @@ -178,11 +178,13 @@ CXXBaseOrMemberInitializer::~CXXBaseOrMemberInitializer() { CXXConstructorDecl * CXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD, - SourceLocation L, IdentifierInfo *Id, + SourceLocation L, DeclarationName N, QualType T, bool isExplicit, bool isInline, bool isImplicitlyDeclared) { + assert(N.getNameKind() == DeclarationName::CXXConstructorName && + "Name must refer to a constructor"); void *Mem = C.getAllocator().Allocate(); - return new (Mem) CXXConstructorDecl(RD, L, Id, T, isExplicit, isInline, + return new (Mem) CXXConstructorDecl(RD, L, N, T, isExplicit, isInline, isImplicitlyDeclared); } @@ -242,54 +244,26 @@ bool CXXConstructorDecl::isConvertingConstructor() const { (getNumParams() > 1 && getParamDecl(1)->getDefaultArg() != 0); } -const char *CXXConstructorDecl::getName() const { - return getParent()->getName(); -} - CXXDestructorDecl * CXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD, - SourceLocation L, IdentifierInfo *Id, + SourceLocation L, DeclarationName N, QualType T, bool isInline, bool isImplicitlyDeclared) { + assert(N.getNameKind() == DeclarationName::CXXDestructorName && + "Name must refer to a destructor"); void *Mem = C.getAllocator().Allocate(); - return new (Mem) CXXDestructorDecl(RD, L, Id, T, isInline, + return new (Mem) CXXDestructorDecl(RD, L, N, T, isInline, isImplicitlyDeclared); } -CXXDestructorDecl::~CXXDestructorDecl() { - delete [] Name; -} - -const char *CXXDestructorDecl::getName() const { - if (!Name) { - std::string Builder = "~"; - Builder += getParent()->getName(); - Name = new char[Builder.size()+1]; - strcpy(Name, Builder.c_str()); - } - return Name; -} - -CXXConversionDecl::~CXXConversionDecl() { - delete [] Name; -} - -const char *CXXConversionDecl::getName() const { - if (!Name) { - std::string Builder = "operator "; - Builder += getConversionType().getAsString(); - Name = new char[Builder.size()+1]; - strcpy(Name, Builder.c_str()); - } - return Name; -} - CXXConversionDecl * CXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD, - SourceLocation L, IdentifierInfo *Id, + SourceLocation L, DeclarationName N, QualType T, bool isInline, bool isExplicit) { + assert(N.getNameKind() == DeclarationName::CXXConversionFunctionName && + "Name must refer to a conversion function"); void *Mem = C.getAllocator().Allocate(); - return new (Mem) CXXConversionDecl(RD, L, Id, T, isInline, isExplicit); + return new (Mem) CXXConversionDecl(RD, L, N, T, isInline, isExplicit); } CXXClassVarDecl *CXXClassVarDecl::Create(ASTContext &C, CXXRecordDecl *RD, @@ -301,9 +275,9 @@ CXXClassVarDecl *CXXClassVarDecl::Create(ASTContext &C, CXXRecordDecl *RD, OverloadedFunctionDecl * OverloadedFunctionDecl::Create(ASTContext &C, DeclContext *DC, - IdentifierInfo *Id) { + DeclarationName N) { void *Mem = C.getAllocator().Allocate(); - return new (Mem) OverloadedFunctionDecl(DC, Id); + return new (Mem) OverloadedFunctionDecl(DC, N); } LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C, diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index 0d006d676d73..558156c4a025 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/lib/AST/DeclObjC.cpp @@ -758,11 +758,11 @@ unsigned ObjCMethodDecl::getSynthesizedMethodSize() const { // syntesized method name is a concatenation of -/+[class-name selector] // Get length of this name. unsigned length = 3; // _I_ or _C_ - length += strlen(getClassInterface()->getName()) +1; // extra for _ + length += strlen(getClassInterface()->getIdentifierName()) +1; // extra for _ NamedDecl *MethodContext = getMethodContext(); if (ObjCCategoryImplDecl *CID = dyn_cast(MethodContext)) - length += strlen(CID->getName()) +1; + length += strlen(CID->getIdentifierName()) +1; length += getSelector().getName().size(); // selector name return length; } diff --git a/clang/lib/AST/DeclSerialization.cpp b/clang/lib/AST/DeclSerialization.cpp index 3df942e8f1f1..5137b720c5be 100644 --- a/clang/lib/AST/DeclSerialization.cpp +++ b/clang/lib/AST/DeclSerialization.cpp @@ -129,12 +129,58 @@ void DeclContext::ReadOutRec(Deserializer& D, ASTContext& C) { void NamedDecl::EmitInRec(Serializer& S) const { Decl::EmitInRec(S); - S.EmitPtr(getIdentifier()); // From NamedDecl. + S.EmitInt(Name.getNameKind()); + + switch (Name.getNameKind()) { + case DeclarationName::Identifier: + S.EmitPtr(Name.getAsIdentifierInfo()); + break; + + case DeclarationName::ObjCZeroArgSelector: + case DeclarationName::ObjCOneArgSelector: + case DeclarationName::ObjCMultiArgSelector: + Name.getObjCSelector().Emit(S); + break; + + case DeclarationName::CXXConstructorName: + case DeclarationName::CXXDestructorName: + case DeclarationName::CXXConversionFunctionName: + Name.getCXXNameType().Emit(S); + break; + } } void NamedDecl::ReadInRec(Deserializer& D, ASTContext& C) { Decl::ReadInRec(D, C); - D.ReadPtr(Identifier); // From NamedDecl. + + DeclarationName::NameKind Kind + = static_cast(D.ReadInt()); + switch (Kind) { + case DeclarationName::Identifier: { + IdentifierInfo *Identifier; + D.ReadPtr(Identifier); + Name = Identifier; + break; + } + + case DeclarationName::ObjCZeroArgSelector: + case DeclarationName::ObjCOneArgSelector: + case DeclarationName::ObjCMultiArgSelector: + Name = Selector::ReadVal(D); + break; + + case DeclarationName::CXXConstructorName: + Name = C.DeclarationNames.getCXXConstructorName(QualType::ReadVal(D)); + break; + + case DeclarationName::CXXDestructorName: + Name = C.DeclarationNames.getCXXDestructorName(QualType::ReadVal(D)); + break; + + case DeclarationName::CXXConversionFunctionName: + Name = C.DeclarationNames.getCXXConversionFunctionName(QualType::ReadVal(D)); + break; + } } //===----------------------------------------------------------------------===// @@ -434,7 +480,7 @@ FunctionDecl* FunctionDecl::CreateImpl(Deserializer& D, ASTContext& C) { void *Mem = C.getAllocator().Allocate(); FunctionDecl* decl = new (Mem) - FunctionDecl(Function, 0, SourceLocation(), NULL, + FunctionDecl(Function, 0, SourceLocation(), DeclarationName(), QualType(), SClass, IsInline, 0); decl->ValueDecl::ReadInRec(D, C); @@ -495,7 +541,7 @@ OverloadedFunctionDecl * OverloadedFunctionDecl::CreateImpl(Deserializer& D, ASTContext& C) { void *Mem = C.getAllocator().Allocate(); OverloadedFunctionDecl* decl = new (Mem) - OverloadedFunctionDecl(0, NULL); + OverloadedFunctionDecl(0, DeclarationName()); decl->NamedDecl::ReadInRec(D, C); diff --git a/clang/lib/AST/DeclarationName.cpp b/clang/lib/AST/DeclarationName.cpp new file mode 100644 index 000000000000..96e194be8c9b --- /dev/null +++ b/clang/lib/AST/DeclarationName.cpp @@ -0,0 +1,166 @@ +//===-- DeclarationName.cpp - Declaration names implementation --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the DeclarationName and DeclarationNameTable +// classes. +// +//===----------------------------------------------------------------------===// +#include "clang/AST/DeclarationName.h" +#include "clang/Basic/IdentifierTable.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/Bitcode/Serialize.h" +#include "llvm/Bitcode/Deserialize.h" +using namespace clang; + +namespace clang { +/// CXXSpecialName - Records the type associated with one of the +/// "special" kinds of declaration names in C++, e.g., constructors, +/// destructors, and conversion functions. +class CXXSpecialName + : public DeclarationNameExtra, public llvm::FoldingSetNode { +public: + QualType Type; + + void Profile(llvm::FoldingSetNodeID &ID) { + ID.AddInteger(ExtraKindOrNumArgs); + ID.AddPointer(Type.getAsOpaquePtr()); + } +}; + +bool operator<(DeclarationName LHS, DeclarationName RHS) { + if (IdentifierInfo *LhsId = LHS.getAsIdentifierInfo()) + if (IdentifierInfo *RhsId = RHS.getAsIdentifierInfo()) + return strcmp(LhsId->getName(), RhsId->getName()) < 0; + + return LHS.getAsOpaqueInteger() < RHS.getAsOpaqueInteger(); +} + +} // end namespace clang + +DeclarationName::DeclarationName(Selector Sel) { + switch (Sel.getNumArgs()) { + case 0: + Ptr = reinterpret_cast(Sel.getAsIdentifierInfo()); + Ptr |= StoredObjCZeroArgSelector; + break; + + case 1: + Ptr = reinterpret_cast(Sel.getAsIdentifierInfo()); + Ptr |= StoredObjCOneArgSelector; + break; + + default: + Ptr = Sel.InfoPtr & ~Selector::ArgFlags; + Ptr |= StoredObjCMultiArgSelectorOrCXXName; + break; + } +} + +DeclarationName::NameKind DeclarationName::getNameKind() const { + switch (getStoredNameKind()) { + case StoredIdentifier: return Identifier; + case StoredObjCZeroArgSelector: return ObjCZeroArgSelector; + case StoredObjCOneArgSelector: return ObjCOneArgSelector; + + case StoredObjCMultiArgSelectorOrCXXName: + switch (getExtra()->ExtraKindOrNumArgs) { + case DeclarationNameExtra::CXXConstructor: + return CXXConstructorName; + + case DeclarationNameExtra::CXXDestructor: + return CXXDestructorName; + + case DeclarationNameExtra::CXXConversionFunction: + return CXXConversionFunctionName; + + default: + return ObjCMultiArgSelector; + } + break; + } + + // Can't actually get here. + return Identifier; +} + +QualType DeclarationName::getCXXNameType() const { + if (CXXSpecialName *CXXName = getAsCXXSpecialName()) + return CXXName->Type; + else + return QualType(); +} + +Selector DeclarationName::getObjCSelector() const { + switch (getNameKind()) { + case ObjCZeroArgSelector: + return Selector(reinterpret_cast(Ptr & ~PtrMask), 0); + + case ObjCOneArgSelector: + return Selector(reinterpret_cast(Ptr & ~PtrMask), 1); + + case ObjCMultiArgSelector: + return Selector(reinterpret_cast(Ptr & ~PtrMask)); + + default: + break; + } + + return Selector(); +} + +DeclarationNameTable::DeclarationNameTable() { + CXXSpecialNamesImpl = new llvm::FoldingSet; +} + +DeclarationNameTable::~DeclarationNameTable() { + delete static_cast*>(CXXSpecialNamesImpl); +} + +DeclarationName +DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind, + QualType Ty) { + assert(Kind >= DeclarationName::CXXConstructorName && + Kind <= DeclarationName::CXXConversionFunctionName && + "Kind must be a C++ special name kind"); + + llvm::FoldingSet *SpecialNames + = static_cast*>(CXXSpecialNamesImpl); + + DeclarationNameExtra::ExtraKind EKind; + switch (Kind) { + case DeclarationName::CXXConstructorName: + EKind = DeclarationNameExtra::CXXConstructor; + break; + case DeclarationName::CXXDestructorName: + EKind = DeclarationNameExtra::CXXDestructor; + break; + case DeclarationName::CXXConversionFunctionName: + EKind = DeclarationNameExtra::CXXConversionFunction; + break; + default: + return DeclarationName(); + } + + // Unique selector, to guarantee there is one per name. + llvm::FoldingSetNodeID ID; + ID.AddInteger(EKind); + ID.AddPointer(Ty.getAsOpaquePtr()); + + void *InsertPos = 0; + if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos)) + return DeclarationName(Name); + + CXXSpecialName *SpecialName = new CXXSpecialName; + SpecialName->ExtraKindOrNumArgs = EKind; + SpecialName->Type = Ty; + + SpecialNames->InsertNode(SpecialName, InsertPos); + return DeclarationName(SpecialName); +} + diff --git a/clang/lib/AST/StmtDumper.cpp b/clang/lib/AST/StmtDumper.cpp index 0b9e62d2c568..a992efba50ae 100644 --- a/clang/lib/AST/StmtDumper.cpp +++ b/clang/lib/AST/StmtDumper.cpp @@ -202,7 +202,7 @@ void StmtDumper::DumpDeclarator(Decl *D) { if (TypedefDecl *localType = dyn_cast(D)) { fprintf(F, "\"typedef %s %s\"", localType->getUnderlyingType().getAsString().c_str(), - localType->getName()); + localType->getIdentifierName()); } else if (ValueDecl *VD = dyn_cast(D)) { fprintf(F, "\""); // Emit storage class for vardecls. @@ -295,14 +295,16 @@ void StmtDumper::VisitDeclRefExpr(DeclRefExpr *Node) { default: fprintf(F,"Decl"); break; } - fprintf(F, "='%s' %p", Node->getDecl()->getName(), (void*)Node->getDecl()); + fprintf(F, "='%s' %p", Node->getDecl()->getName().c_str(), + (void*)Node->getDecl()); } void StmtDumper::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) { DumpExpr(Node); fprintf(F, " %sDecl='%s' %p", Node->getDecl()->getDeclKindName(), - Node->getDecl()->getName(), (void*)Node->getDecl()); + Node->getDecl()->getIdentifierName(), + (void*)Node->getDecl()); if (Node->isFreeIvar()) fprintf(F, " isFreeIvar"); } @@ -373,7 +375,8 @@ void StmtDumper::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) { void StmtDumper::VisitMemberExpr(MemberExpr *Node) { DumpExpr(Node); fprintf(F, " %s%s %p", Node->isArrow() ? "->" : ".", - Node->getMemberDecl()->getName(), (void*)Node->getMemberDecl()); + Node->getMemberDecl()->getName().c_str(), + (void*)Node->getMemberDecl()); } void StmtDumper::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) { DumpExpr(Node); @@ -461,7 +464,7 @@ void StmtDumper::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) { DumpExpr(Node); fprintf(F, " "); - fprintf(F, "%s", Node->getProtocol()->getName()); + fprintf(F, "%s", Node->getProtocol()->getIdentifierName()); } void StmtDumper::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) { @@ -474,7 +477,8 @@ void StmtDumper::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) { Getter->getSelector().getName().c_str(), Setter ? Setter->getSelector().getName().c_str() : "(null)"); } else { - fprintf(F, " Kind=PropertyRef Property=\"%s\"", Node->getProperty()->getName()); + fprintf(F, " Kind=PropertyRef Property=\"%s\"", + Node->getProperty()->getIdentifierName()); } } diff --git a/clang/lib/Basic/IdentifierTable.cpp b/clang/lib/Basic/IdentifierTable.cpp index 4d737c50bc01..b83266d1ff8c 100644 --- a/clang/lib/Basic/IdentifierTable.cpp +++ b/clang/lib/Basic/IdentifierTable.cpp @@ -297,22 +297,22 @@ unsigned llvm::DenseMapInfo::getHashValue(clang::Selector S) { return DenseMapInfo::getHashValue(S.getAsOpaquePtr()); } - +namespace clang { /// MultiKeywordSelector - One of these variable length records is kept for each /// selector containing more than one keyword. We use a folding set /// to unique aggregate names (keyword selectors in ObjC parlance). Access to /// this class is provided strictly through Selector. -namespace clang { -class MultiKeywordSelector : public llvm::FoldingSetNode { +class MultiKeywordSelector + : public DeclarationNameExtra, public llvm::FoldingSetNode { friend SelectorTable* SelectorTable::CreateAndRegister(llvm::Deserializer&); - MultiKeywordSelector(unsigned nKeys) : NumArgs(nKeys) {} + MultiKeywordSelector(unsigned nKeys) { + ExtraKindOrNumArgs = NUM_EXTRA_KINDS + nKeys; + } public: - unsigned NumArgs; - // Constructor for keyword selectors. MultiKeywordSelector(unsigned nKeys, IdentifierInfo **IIV) { assert((nKeys > 1) && "not a multi-keyword selector"); - NumArgs = nKeys; + ExtraKindOrNumArgs = NUM_EXTRA_KINDS + nKeys; // Fill in the trailing keyword array. IdentifierInfo **KeyInfo = reinterpret_cast(this+1); @@ -323,17 +323,17 @@ public: // getName - Derive the full selector name and return it. std::string getName() const; - unsigned getNumArgs() const { return NumArgs; } + unsigned getNumArgs() const { return ExtraKindOrNumArgs - NUM_EXTRA_KINDS; } typedef IdentifierInfo *const *keyword_iterator; keyword_iterator keyword_begin() const { return reinterpret_cast(this+1); } keyword_iterator keyword_end() const { - return keyword_begin()+NumArgs; + return keyword_begin()+getNumArgs(); } IdentifierInfo *getIdentifierInfoForSlot(unsigned i) const { - assert(i < NumArgs && "getIdentifierInfoForSlot(): illegal index"); + assert(i < getNumArgs() && "getIdentifierInfoForSlot(): illegal index"); return keyword_begin()[i]; } static void Profile(llvm::FoldingSetNodeID &ID, @@ -343,7 +343,7 @@ public: ID.AddPointer(ArgTys[i]); } void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, keyword_begin(), NumArgs); + Profile(ID, keyword_begin(), getNumArgs()); } }; } // end namespace clang. diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 9a04a83d6e62..55ce237e14f8 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -152,7 +152,7 @@ llvm::DIType CGDebugInfo::CreateType(const TypedefType *Ty, // We don't set size information, but do specify where the typedef was // declared. - const char *TyName = Ty->getDecl()->getName(); + const char *TyName = Ty->getDecl()->getIdentifierName(); SourceLocation DefLoc = Ty->getDecl()->getLocation(); llvm::DICompileUnit DefUnit = getOrCreateCompileUnit(DefLoc); @@ -206,7 +206,7 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty, SourceManager &SM = M->getContext().getSourceManager(); // Get overall information about the record type for the debug info. - const char *Name = Decl->getName(); + const char *Name = Decl->getIdentifierName(); if (Name == 0) Name = ""; llvm::DICompileUnit DefUnit = getOrCreateCompileUnit(Decl->getLocation()); @@ -242,7 +242,7 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty, FieldDecl *Field = *I; llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit); - const char *FieldName = Field->getName(); + const char *FieldName = Field->getIdentifierName(); if (FieldName == 0) FieldName = ""; // Get the location for the field. @@ -301,7 +301,8 @@ llvm::DIType CGDebugInfo::CreateType(const EnumType *Ty, llvm::DIArray EltArray = DebugFactory.GetOrCreateArray(&Enumerators[0], Enumerators.size()); - const char *EnumName = Decl->getName() ? Decl->getName() : ""; + const char *EnumName + = Decl->getIdentifierName() ? Decl->getIdentifierName() : ""; SourceLocation DefLoc = Decl->getLocation(); llvm::DICompileUnit DefUnit = getOrCreateCompileUnit(DefLoc); SourceManager &SM = M->getContext().getSourceManager(); @@ -515,7 +516,7 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var, llvm::DICompileUnit Unit = getOrCreateCompileUnit(Decl->getLocation()); SourceManager &SM = M->getContext().getSourceManager(); uint64_t LineNo = SM.getLogicalLineNumber(Decl->getLocation()); - const char *Name = Decl->getName(); + const char *Name = Decl->getIdentifierName(); DebugFactory.CreateGlobalVariable(Unit, Name, Name, "", Unit, LineNo, getOrCreateType(Decl->getType(), Unit), diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index e54c4b386db9..7a86d24801f1 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -146,7 +146,7 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) { if (!Target.useGlobalsForAutomaticVariables()) { // A normal fixed sized variable becomes an alloca in the entry block. const llvm::Type *LTy = ConvertType(Ty); - llvm::AllocaInst * Alloc = CreateTempAlloca(LTy, D.getName()); + llvm::AllocaInst * Alloc = CreateTempAlloca(LTy, D.getIdentifierName()); unsigned align = getContext().getTypeAlign(Ty); if (const AlignedAttr* AA = D.getAttr()) align = std::max(align, AA->getAlignment()); @@ -164,7 +164,7 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) { // FIXME: VLA: Add VLA support. For now just make up enough to let // the compile go through. const llvm::Type *LTy = ConvertType(Ty); - llvm::AllocaInst * Alloc = CreateTempAlloca(LTy, D.getName()); + llvm::AllocaInst * Alloc = CreateTempAlloca(LTy, D.getIdentifierName()); DeclPtr = Alloc; } diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp index 4726be211515..0833b0832d74 100644 --- a/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/clang/lib/CodeGen/CGObjCGNU.cpp @@ -561,7 +561,7 @@ llvm::Value *CGObjCGNU::GenerateProtocolRef(CGBuilderTy &Builder, void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) { ASTContext &Context = CGM.getContext(); - const char *ProtocolName = PD->getName(); + const char *ProtocolName = PD->getIdentifierName(); llvm::SmallVector Protocols; for (ObjCProtocolDecl::protocol_iterator PI = PD->protocol_begin(), E = PD->protocol_end(); PI != E; ++PI) @@ -616,8 +616,8 @@ void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) { } void CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) { - const char *ClassName = OCD->getClassInterface()->getName(); - const char *CategoryName = OCD->getName(); + const char *ClassName = OCD->getClassInterface()->getIdentifierName(); + const char *CategoryName = OCD->getIdentifierName(); // Collect information about instance methods llvm::SmallVector InstanceMethodSels; llvm::SmallVector InstanceMethodTypes; @@ -675,12 +675,12 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) { OID->getClassInterface()->getSuperClass(); const char * SuperClassName = NULL; if (SuperClassDecl) { - SuperClassName = SuperClassDecl->getName(); + SuperClassName = SuperClassDecl->getIdentifierName(); } // Get the class name ObjCInterfaceDecl * ClassDecl = (ObjCInterfaceDecl*)OID->getClassInterface(); - const char * ClassName = ClassDecl->getName(); + const char * ClassName = ClassDecl->getIdentifierName(); // Get the size of instances. For runtimes that support late-bound instances // this should probably be something different (size just of instance diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 296b1af5518d..a8f6bbab9b4f 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -638,7 +638,7 @@ llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) { // over. LazySymbols.insert(&CGM.getContext().Idents.get("Protocol")); - const char *ProtocolName = PD->getName(); + const char *ProtocolName = PD->getIdentifierName(); // Construct method lists. std::vector InstanceMethods, ClassMethods; @@ -1050,7 +1050,7 @@ static bool IsClassHidden(const ObjCInterfaceDecl *ID) { void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) { DefinedSymbols.insert(ID->getIdentifier()); - const char *ClassName = ID->getName(); + const char *ClassName = ID->getIdentifierName(); // FIXME: Gross ObjCInterfaceDecl *Interface = const_cast(ID->getClassInterface()); @@ -1143,7 +1143,7 @@ llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID, llvm::Constant *Protocols, const llvm::Type *InterfaceTy, const ConstantVector &Methods) { - const char *ClassName = ID->getName(); + const char *ClassName = ID->getIdentifierName(); unsigned Flags = eClassFlags_Meta; unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ClassTy); diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index ff05f6e5855a..b358993665d6 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -121,7 +121,7 @@ void CodeGenFunction::StartFunction(const Decl *D, QualType RetTy, if (CGDebugInfo *DI = CGM.getDebugInfo()) { DI->setLocation(StartLoc); if (const FunctionDecl *FD = dyn_cast(D)) { - DI->EmitFunctionStart(FD->getName(), RetTy, CurFn, Builder); + DI->EmitFunctionStart(FD->getIdentifierName(), RetTy, CurFn, Builder); } else { // Just use LLVM function name. DI->EmitFunctionStart(Fn->getName().c_str(), diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 1ecaaa370a4e..48073694a32c 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -877,9 +877,13 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { bool isInvalidDecl = CheckConstructorDeclarator(D, R, SC); // Create the new declaration + QualType ClassType = Context.getTypeDeclType(cast(DC)); + ClassType = Context.getCanonicalType(ClassType); + DeclarationName ConName + = Context.DeclarationNames.getCXXConstructorName(ClassType); NewFD = CXXConstructorDecl::Create(Context, cast(DC), - D.getIdentifierLoc(), II, R, + D.getIdentifierLoc(), ConName, R, isExplicit, isInline, /*isImplicitlyDeclared=*/false); @@ -890,9 +894,14 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { if (DC->isCXXRecord()) { bool isInvalidDecl = CheckDestructorDeclarator(D, R, SC); + QualType ClassType = Context.getTypeDeclType(cast(DC)); + ClassType = Context.getCanonicalType(ClassType); + DeclarationName DesName + = Context.DeclarationNames.getCXXDestructorName(ClassType); + NewFD = CXXDestructorDecl::Create(Context, cast(DC), - D.getIdentifierLoc(), II, R, + D.getIdentifierLoc(), DesName, R, isInline, /*isImplicitlyDeclared=*/false); @@ -916,9 +925,14 @@ 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(DC), - D.getIdentifierLoc(), II, R, + D.getIdentifierLoc(), ConvName, R, isInline, isExplicit); if (isInvalidDecl) diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index f8369b3d8da2..2fb1332281ea 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -725,6 +725,9 @@ void Sema::ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc, /// [special]p1). This routine can only be executed just before the /// definition of the class is complete. void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) { + QualType ClassType = Context.getTypeDeclType(ClassDecl); + ClassType = Context.getCanonicalType(ClassType); + if (!ClassDecl->hasUserDeclaredConstructor()) { // C++ [class.ctor]p5: // A default constructor for a class X is a constructor of class X @@ -732,10 +735,11 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) { // user-declared constructor for class X, a default constructor is // implicitly declared. An implicitly-declared default constructor // is an inline public member of its class. + DeclarationName Name + = Context.DeclarationNames.getCXXConstructorName(ClassType); CXXConstructorDecl *DefaultCon = CXXConstructorDecl::Create(Context, ClassDecl, - ClassDecl->getLocation(), - &Context.Idents.getConstructorId(), + ClassDecl->getLocation(), Name, Context.getFunctionType(Context.VoidTy, 0, 0, false, 0), /*isExplicit=*/false, @@ -798,10 +802,11 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) { // An implicitly-declared copy constructor is an inline public // member of its class. + DeclarationName Name + = Context.DeclarationNames.getCXXConstructorName(ClassType); CXXConstructorDecl *CopyConstructor = CXXConstructorDecl::Create(Context, ClassDecl, - ClassDecl->getLocation(), - &Context.Idents.getConstructorId(), + ClassDecl->getLocation(), Name, Context.getFunctionType(Context.VoidTy, &ArgType, 1, false, 0), @@ -825,10 +830,11 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) { // If a class has no user-declared destructor, a destructor is // declared implicitly. An implicitly-declared destructor is an // inline public member of its class. + DeclarationName Name + = Context.DeclarationNames.getCXXDestructorName(ClassType); CXXDestructorDecl *Destructor = CXXDestructorDecl::Create(Context, ClassDecl, - ClassDecl->getLocation(), - &Context.Idents.getConstructorId(), + ClassDecl->getLocation(), Name, Context.getFunctionType(Context.VoidTy, 0, 0, false, 0), /*isInline=*/true, diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 6c17d5f1f6c9..8eeb2d367d70 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -302,7 +302,8 @@ Sema::ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl) { E = IDecl->classprop_end(); I != E; ++I) { ObjCPropertyDecl *PDecl = (*I); if (SuperPDecl->getIdentifier() == PDecl->getIdentifier()) - DiagnosePropertyMismatch(PDecl, SuperPDecl, SDecl->getName()); + DiagnosePropertyMismatch(PDecl, SuperPDecl, + SDecl->getIdentifierName()); } } } @@ -329,7 +330,7 @@ Sema::MergeOneProtocolPropertiesIntoClass(ObjCInterfaceDecl *IDecl, mergeProperties.push_back(Pr); else // Property protocol already exist in class. Diagnose any mismatch. - DiagnosePropertyMismatch((*CP), Pr, PDecl->getName()); + DiagnosePropertyMismatch((*CP), Pr, PDecl->getIdentifierName()); } IDecl->mergeProperties(&mergeProperties[0], mergeProperties.size()); } diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 58ab5aa7596b..f18b98fc13ac 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -209,7 +209,7 @@ void UserDefinedConversionSequence::DebugPrint() const { Before.DebugPrint(); fprintf(stderr, " -> "); } - fprintf(stderr, "'%s'", ConversionFunction->getName()); + fprintf(stderr, "'%s'", ConversionFunction->getName().c_str()); if (After.First || After.Second || After.Third) { fprintf(stderr, " -> "); After.DebugPrint();