| Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 1 | //===--- Decl.cpp - Declaration AST Node Implementation -------------------===// | 
 | 2 | // | 
 | 3 | //                     The LLVM Compiler Infrastructure | 
 | 4 | // | 
| Chris Lattner | 0bc735f | 2007-12-29 19:59:25 +0000 | [diff] [blame] | 5 | // This file is distributed under the University of Illinois Open Source | 
 | 6 | // License. See LICENSE.TXT for details. | 
| Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 7 | // | 
 | 8 | //===----------------------------------------------------------------------===// | 
 | 9 | // | 
| Argyrios Kyrtzidis | e184bae | 2008-06-04 13:04:04 +0000 | [diff] [blame] | 10 | // This file implements the Decl subclasses. | 
| Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 11 | // | 
 | 12 | //===----------------------------------------------------------------------===// | 
 | 13 |  | 
 | 14 | #include "clang/AST/Decl.h" | 
| Douglas Gregor | 2a3009a | 2009-02-03 19:21:40 +0000 | [diff] [blame] | 15 | #include "clang/AST/DeclCXX.h" | 
| Steve Naroff | 0de21fd | 2009-02-22 19:35:57 +0000 | [diff] [blame] | 16 | #include "clang/AST/DeclObjC.h" | 
| Douglas Gregor | 7da97d0 | 2009-05-10 22:57:19 +0000 | [diff] [blame] | 17 | #include "clang/AST/DeclTemplate.h" | 
| Chris Lattner | 6c2b6eb | 2008-03-15 06:12:44 +0000 | [diff] [blame] | 18 | #include "clang/AST/ASTContext.h" | 
| Argyrios Kyrtzidis | b17166c | 2009-08-19 01:27:32 +0000 | [diff] [blame] | 19 | #include "clang/AST/TypeLoc.h" | 
| Daniel Dunbar | e91593e | 2008-08-11 04:54:23 +0000 | [diff] [blame] | 20 | #include "clang/AST/Stmt.h" | 
| Nuno Lopes | 99f06ba | 2008-12-17 23:39:55 +0000 | [diff] [blame] | 21 | #include "clang/AST/Expr.h" | 
| Anders Carlsson | 337cba4 | 2009-12-15 19:16:31 +0000 | [diff] [blame] | 22 | #include "clang/AST/ExprCXX.h" | 
| Douglas Gregor | d249e1d1f | 2009-05-29 20:38:28 +0000 | [diff] [blame] | 23 | #include "clang/AST/PrettyPrinter.h" | 
| Chris Lattner | 1b63e4f | 2009-06-14 01:54:56 +0000 | [diff] [blame] | 24 | #include "clang/Basic/Builtins.h" | 
| Daniel Dunbar | e91593e | 2008-08-11 04:54:23 +0000 | [diff] [blame] | 25 | #include "clang/Basic/IdentifierTable.h" | 
| John McCall | f1bbbb4 | 2009-09-04 01:14:41 +0000 | [diff] [blame] | 26 | #include "clang/Parse/DeclSpec.h" | 
 | 27 | #include "llvm/Support/ErrorHandling.h" | 
| Ted Kremenek | 27f8a28 | 2008-05-20 00:43:19 +0000 | [diff] [blame] | 28 |  | 
| Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 29 | using namespace clang; | 
 | 30 |  | 
| Argyrios Kyrtzidis | b17166c | 2009-08-19 01:27:32 +0000 | [diff] [blame] | 31 | /// \brief Return the TypeLoc wrapper for the type source info. | 
| John McCall | a93c934 | 2009-12-07 02:54:59 +0000 | [diff] [blame] | 32 | TypeLoc TypeSourceInfo::getTypeLoc() const { | 
| Argyrios Kyrtzidis | b735471 | 2009-09-29 19:40:20 +0000 | [diff] [blame] | 33 |   return TypeLoc(Ty, (void*)(this + 1)); | 
| Argyrios Kyrtzidis | b17166c | 2009-08-19 01:27:32 +0000 | [diff] [blame] | 34 | } | 
| Chris Lattner | 0b2b6e1 | 2009-03-04 06:34:08 +0000 | [diff] [blame] | 35 |  | 
| Chris Lattner | d3b9065 | 2008-03-15 05:43:15 +0000 | [diff] [blame] | 36 | //===----------------------------------------------------------------------===// | 
| Douglas Gregor | 4afa39d | 2009-01-20 01:17:11 +0000 | [diff] [blame] | 37 | // NamedDecl Implementation | 
| Argyrios Kyrtzidis | 5239304 | 2008-11-09 23:41:00 +0000 | [diff] [blame] | 38 | //===----------------------------------------------------------------------===// | 
 | 39 |  | 
| Douglas Gregor | 0b6bc8b | 2010-02-03 09:33:45 +0000 | [diff] [blame] | 40 | /// \brief Get the most restrictive linkage for the types in the given | 
 | 41 | /// template parameter list. | 
 | 42 | static Linkage  | 
 | 43 | getLinkageForTemplateParameterList(const TemplateParameterList *Params) { | 
 | 44 |   Linkage L = ExternalLinkage; | 
 | 45 |   for (TemplateParameterList::const_iterator P = Params->begin(), | 
 | 46 |                                           PEnd = Params->end(); | 
 | 47 |        P != PEnd; ++P) { | 
 | 48 |     if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) | 
 | 49 |       if (!NTTP->getType()->isDependentType()) { | 
 | 50 |         L = minLinkage(L, NTTP->getType()->getLinkage()); | 
 | 51 |         continue; | 
 | 52 |       } | 
 | 53 |  | 
 | 54 |     if (TemplateTemplateParmDecl *TTP | 
 | 55 |                                    = dyn_cast<TemplateTemplateParmDecl>(*P)) { | 
 | 56 |       L = minLinkage(L,  | 
 | 57 |             getLinkageForTemplateParameterList(TTP->getTemplateParameters())); | 
 | 58 |     } | 
 | 59 |   } | 
 | 60 |  | 
 | 61 |   return L; | 
 | 62 | } | 
 | 63 |  | 
 | 64 | /// \brief Get the most restrictive linkage for the types and | 
 | 65 | /// declarations in the given template argument list. | 
 | 66 | static Linkage getLinkageForTemplateArgumentList(const TemplateArgument *Args, | 
 | 67 |                                                  unsigned NumArgs) { | 
 | 68 |   Linkage L = ExternalLinkage; | 
 | 69 |  | 
 | 70 |   for (unsigned I = 0; I != NumArgs; ++I) { | 
 | 71 |     switch (Args[I].getKind()) { | 
 | 72 |     case TemplateArgument::Null: | 
 | 73 |     case TemplateArgument::Integral: | 
 | 74 |     case TemplateArgument::Expression: | 
 | 75 |       break; | 
 | 76 |        | 
 | 77 |     case TemplateArgument::Type: | 
 | 78 |       L = minLinkage(L, Args[I].getAsType()->getLinkage()); | 
 | 79 |       break; | 
 | 80 |  | 
 | 81 |     case TemplateArgument::Declaration: | 
 | 82 |       if (NamedDecl *ND = dyn_cast<NamedDecl>(Args[I].getAsDecl())) | 
 | 83 |         L = minLinkage(L, ND->getLinkage()); | 
 | 84 |       if (ValueDecl *VD = dyn_cast<ValueDecl>(Args[I].getAsDecl())) | 
 | 85 |         L = minLinkage(L, VD->getType()->getLinkage()); | 
 | 86 |       break; | 
 | 87 |  | 
 | 88 |     case TemplateArgument::Template: | 
 | 89 |       if (TemplateDecl *Template | 
 | 90 |                                 = Args[I].getAsTemplate().getAsTemplateDecl()) | 
 | 91 |         L = minLinkage(L, Template->getLinkage()); | 
 | 92 |       break; | 
 | 93 |  | 
 | 94 |     case TemplateArgument::Pack: | 
 | 95 |       L = minLinkage(L,  | 
 | 96 |                      getLinkageForTemplateArgumentList(Args[I].pack_begin(), | 
 | 97 |                                                        Args[I].pack_size())); | 
 | 98 |       break; | 
 | 99 |     } | 
 | 100 |   } | 
 | 101 |  | 
 | 102 |   return L; | 
 | 103 | } | 
 | 104 |  | 
 | 105 | static Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) { | 
| Douglas Gregor | d85b5b9 | 2009-11-25 22:24:25 +0000 | [diff] [blame] | 106 |   assert(D->getDeclContext()->getLookupContext()->isFileContext() && | 
 | 107 |          "Not a name having namespace scope"); | 
 | 108 |   ASTContext &Context = D->getASTContext(); | 
 | 109 |  | 
 | 110 |   // C++ [basic.link]p3: | 
 | 111 |   //   A name having namespace scope (3.3.6) has internal linkage if it | 
 | 112 |   //   is the name of | 
 | 113 |   //     - an object, reference, function or function template that is | 
 | 114 |   //       explicitly declared static; or, | 
 | 115 |   // (This bullet corresponds to C99 6.2.2p3.) | 
 | 116 |   if (const VarDecl *Var = dyn_cast<VarDecl>(D)) { | 
 | 117 |     // Explicitly declared static. | 
 | 118 |     if (Var->getStorageClass() == VarDecl::Static) | 
| Douglas Gregor | 0b6bc8b | 2010-02-03 09:33:45 +0000 | [diff] [blame] | 119 |       return InternalLinkage; | 
| Douglas Gregor | d85b5b9 | 2009-11-25 22:24:25 +0000 | [diff] [blame] | 120 |  | 
 | 121 |     // - an object or reference that is explicitly declared const | 
 | 122 |     //   and neither explicitly declared extern nor previously | 
 | 123 |     //   declared to have external linkage; or | 
 | 124 |     // (there is no equivalent in C99) | 
 | 125 |     if (Context.getLangOptions().CPlusPlus && | 
| Eli Friedman | e9d6554 | 2009-11-26 03:04:01 +0000 | [diff] [blame] | 126 |         Var->getType().isConstant(Context) &&  | 
| Douglas Gregor | d85b5b9 | 2009-11-25 22:24:25 +0000 | [diff] [blame] | 127 |         Var->getStorageClass() != VarDecl::Extern && | 
 | 128 |         Var->getStorageClass() != VarDecl::PrivateExtern) { | 
 | 129 |       bool FoundExtern = false; | 
 | 130 |       for (const VarDecl *PrevVar = Var->getPreviousDeclaration(); | 
 | 131 |            PrevVar && !FoundExtern;  | 
 | 132 |            PrevVar = PrevVar->getPreviousDeclaration()) | 
| Douglas Gregor | 0b6bc8b | 2010-02-03 09:33:45 +0000 | [diff] [blame] | 133 |         if (isExternalLinkage(PrevVar->getLinkage())) | 
| Douglas Gregor | d85b5b9 | 2009-11-25 22:24:25 +0000 | [diff] [blame] | 134 |           FoundExtern = true; | 
 | 135 |        | 
 | 136 |       if (!FoundExtern) | 
| Douglas Gregor | 0b6bc8b | 2010-02-03 09:33:45 +0000 | [diff] [blame] | 137 |         return InternalLinkage; | 
| Douglas Gregor | d85b5b9 | 2009-11-25 22:24:25 +0000 | [diff] [blame] | 138 |     } | 
 | 139 |   } else if (isa<FunctionDecl>(D) || isa<FunctionTemplateDecl>(D)) { | 
| Douglas Gregor | 0b6bc8b | 2010-02-03 09:33:45 +0000 | [diff] [blame] | 140 |     // C++ [temp]p4: | 
 | 141 |     //   A non-member function template can have internal linkage; any | 
 | 142 |     //   other template name shall have external linkage. | 
| Douglas Gregor | d85b5b9 | 2009-11-25 22:24:25 +0000 | [diff] [blame] | 143 |     const FunctionDecl *Function = 0; | 
 | 144 |     if (const FunctionTemplateDecl *FunTmpl | 
 | 145 |                                         = dyn_cast<FunctionTemplateDecl>(D)) | 
 | 146 |       Function = FunTmpl->getTemplatedDecl(); | 
 | 147 |     else | 
 | 148 |       Function = cast<FunctionDecl>(D); | 
 | 149 |  | 
 | 150 |     // Explicitly declared static. | 
 | 151 |     if (Function->getStorageClass() == FunctionDecl::Static) | 
| Douglas Gregor | 0b6bc8b | 2010-02-03 09:33:45 +0000 | [diff] [blame] | 152 |       return InternalLinkage; | 
| Douglas Gregor | d85b5b9 | 2009-11-25 22:24:25 +0000 | [diff] [blame] | 153 |   } else if (const FieldDecl *Field = dyn_cast<FieldDecl>(D)) { | 
 | 154 |     //   - a data member of an anonymous union. | 
 | 155 |     if (cast<RecordDecl>(Field->getDeclContext())->isAnonymousStructOrUnion()) | 
| Douglas Gregor | 0b6bc8b | 2010-02-03 09:33:45 +0000 | [diff] [blame] | 156 |       return InternalLinkage; | 
| Douglas Gregor | d85b5b9 | 2009-11-25 22:24:25 +0000 | [diff] [blame] | 157 |   } | 
 | 158 |  | 
 | 159 |   // C++ [basic.link]p4: | 
 | 160 |    | 
 | 161 |   //   A name having namespace scope has external linkage if it is the | 
 | 162 |   //   name of | 
 | 163 |   // | 
 | 164 |   //     - an object or reference, unless it has internal linkage; or | 
 | 165 |   if (const VarDecl *Var = dyn_cast<VarDecl>(D)) { | 
 | 166 |     if (!Context.getLangOptions().CPlusPlus && | 
 | 167 |         (Var->getStorageClass() == VarDecl::Extern || | 
 | 168 |          Var->getStorageClass() == VarDecl::PrivateExtern)) { | 
 | 169 |       // C99 6.2.2p4: | 
 | 170 |       //   For an identifier declared with the storage-class specifier | 
 | 171 |       //   extern in a scope in which a prior declaration of that | 
 | 172 |       //   identifier is visible, if the prior declaration specifies | 
 | 173 |       //   internal or external linkage, the linkage of the identifier | 
 | 174 |       //   at the later declaration is the same as the linkage | 
 | 175 |       //   specified at the prior declaration. If no prior declaration | 
 | 176 |       //   is visible, or if the prior declaration specifies no | 
 | 177 |       //   linkage, then the identifier has external linkage. | 
 | 178 |       if (const VarDecl *PrevVar = Var->getPreviousDeclaration()) { | 
| Douglas Gregor | 0b6bc8b | 2010-02-03 09:33:45 +0000 | [diff] [blame] | 179 |         if (Linkage L = PrevVar->getLinkage()) | 
| Douglas Gregor | d85b5b9 | 2009-11-25 22:24:25 +0000 | [diff] [blame] | 180 |           return L; | 
 | 181 |       } | 
 | 182 |     } | 
 | 183 |  | 
 | 184 |     // C99 6.2.2p5: | 
 | 185 |     //   If the declaration of an identifier for an object has file | 
 | 186 |     //   scope and no storage-class specifier, its linkage is | 
 | 187 |     //   external. | 
| Douglas Gregor | 0b6bc8b | 2010-02-03 09:33:45 +0000 | [diff] [blame] | 188 |     if (Var->isInAnonymousNamespace()) | 
 | 189 |       return UniqueExternalLinkage; | 
 | 190 |  | 
 | 191 |     return ExternalLinkage; | 
| Douglas Gregor | d85b5b9 | 2009-11-25 22:24:25 +0000 | [diff] [blame] | 192 |   } | 
 | 193 |  | 
 | 194 |   //     - a function, unless it has internal linkage; or | 
 | 195 |   if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) { | 
 | 196 |     // C99 6.2.2p5: | 
 | 197 |     //   If the declaration of an identifier for a function has no | 
 | 198 |     //   storage-class specifier, its linkage is determined exactly | 
 | 199 |     //   as if it were declared with the storage-class specifier | 
 | 200 |     //   extern. | 
 | 201 |     if (!Context.getLangOptions().CPlusPlus && | 
 | 202 |         (Function->getStorageClass() == FunctionDecl::Extern || | 
 | 203 |          Function->getStorageClass() == FunctionDecl::PrivateExtern || | 
 | 204 |          Function->getStorageClass() == FunctionDecl::None)) { | 
 | 205 |       // C99 6.2.2p4: | 
 | 206 |       //   For an identifier declared with the storage-class specifier | 
 | 207 |       //   extern in a scope in which a prior declaration of that | 
 | 208 |       //   identifier is visible, if the prior declaration specifies | 
 | 209 |       //   internal or external linkage, the linkage of the identifier | 
 | 210 |       //   at the later declaration is the same as the linkage | 
 | 211 |       //   specified at the prior declaration. If no prior declaration | 
 | 212 |       //   is visible, or if the prior declaration specifies no | 
 | 213 |       //   linkage, then the identifier has external linkage. | 
 | 214 |       if (const FunctionDecl *PrevFunc = Function->getPreviousDeclaration()) { | 
| Douglas Gregor | 0b6bc8b | 2010-02-03 09:33:45 +0000 | [diff] [blame] | 215 |         if (Linkage L = PrevFunc->getLinkage()) | 
| Douglas Gregor | d85b5b9 | 2009-11-25 22:24:25 +0000 | [diff] [blame] | 216 |           return L; | 
 | 217 |       } | 
 | 218 |     } | 
 | 219 |  | 
| Douglas Gregor | 0b6bc8b | 2010-02-03 09:33:45 +0000 | [diff] [blame] | 220 |     if (Function->isInAnonymousNamespace()) | 
 | 221 |       return UniqueExternalLinkage; | 
 | 222 |  | 
 | 223 |     if (FunctionTemplateSpecializationInfo *SpecInfo | 
 | 224 |                                = Function->getTemplateSpecializationInfo()) { | 
 | 225 |       Linkage L = SpecInfo->getTemplate()->getLinkage(); | 
 | 226 |       const TemplateArgumentList &TemplateArgs = *SpecInfo->TemplateArguments; | 
 | 227 |       L = minLinkage(L,  | 
 | 228 |                      getLinkageForTemplateArgumentList( | 
 | 229 |                                           TemplateArgs.getFlatArgumentList(),  | 
 | 230 |                                           TemplateArgs.flat_size())); | 
 | 231 |       return L; | 
 | 232 |     } | 
 | 233 |  | 
 | 234 |     return ExternalLinkage; | 
| Douglas Gregor | d85b5b9 | 2009-11-25 22:24:25 +0000 | [diff] [blame] | 235 |   } | 
 | 236 |  | 
 | 237 |   //     - a named class (Clause 9), or an unnamed class defined in a | 
 | 238 |   //       typedef declaration in which the class has the typedef name | 
 | 239 |   //       for linkage purposes (7.1.3); or | 
 | 240 |   //     - a named enumeration (7.2), or an unnamed enumeration | 
 | 241 |   //       defined in a typedef declaration in which the enumeration | 
 | 242 |   //       has the typedef name for linkage purposes (7.1.3); or | 
 | 243 |   if (const TagDecl *Tag = dyn_cast<TagDecl>(D)) | 
| Douglas Gregor | 0b6bc8b | 2010-02-03 09:33:45 +0000 | [diff] [blame] | 244 |     if (Tag->getDeclName() || Tag->getTypedefForAnonDecl()) { | 
 | 245 |       if (Tag->isInAnonymousNamespace()) | 
 | 246 |         return UniqueExternalLinkage; | 
 | 247 |  | 
 | 248 |       // If this is a class template specialization, consider the | 
 | 249 |       // linkage of the template and template arguments. | 
 | 250 |       if (const ClassTemplateSpecializationDecl *Spec | 
 | 251 |             = dyn_cast<ClassTemplateSpecializationDecl>(Tag)) { | 
 | 252 |         const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); | 
 | 253 |         Linkage L = getLinkageForTemplateArgumentList( | 
 | 254 |                                           TemplateArgs.getFlatArgumentList(), | 
 | 255 |                                                  TemplateArgs.flat_size()); | 
 | 256 |         return minLinkage(L, Spec->getSpecializedTemplate()->getLinkage()); | 
 | 257 |       } | 
 | 258 |  | 
 | 259 |       return ExternalLinkage; | 
 | 260 |     } | 
| Douglas Gregor | d85b5b9 | 2009-11-25 22:24:25 +0000 | [diff] [blame] | 261 |  | 
 | 262 |   //     - an enumerator belonging to an enumeration with external linkage; | 
| Douglas Gregor | 0b6bc8b | 2010-02-03 09:33:45 +0000 | [diff] [blame] | 263 |   if (isa<EnumConstantDecl>(D)) { | 
 | 264 |     Linkage L = cast<NamedDecl>(D->getDeclContext())->getLinkage(); | 
 | 265 |     if (isExternalLinkage(L)) | 
 | 266 |       return L; | 
 | 267 |   } | 
| Douglas Gregor | d85b5b9 | 2009-11-25 22:24:25 +0000 | [diff] [blame] | 268 |  | 
 | 269 |   //     - a template, unless it is a function template that has | 
 | 270 |   //       internal linkage (Clause 14); | 
| Douglas Gregor | 0b6bc8b | 2010-02-03 09:33:45 +0000 | [diff] [blame] | 271 |   if (const TemplateDecl *Template = dyn_cast<TemplateDecl>(D)) { | 
 | 272 |     if (D->isInAnonymousNamespace()) | 
 | 273 |       return UniqueExternalLinkage; | 
 | 274 |  | 
 | 275 |     return getLinkageForTemplateParameterList( | 
 | 276 |                                          Template->getTemplateParameters()); | 
 | 277 |   } | 
| Douglas Gregor | d85b5b9 | 2009-11-25 22:24:25 +0000 | [diff] [blame] | 278 |  | 
 | 279 |   //     - a namespace (7.3), unless it is declared within an unnamed | 
 | 280 |   //       namespace. | 
 | 281 |   if (isa<NamespaceDecl>(D) && !D->isInAnonymousNamespace()) | 
| Douglas Gregor | 0b6bc8b | 2010-02-03 09:33:45 +0000 | [diff] [blame] | 282 |     return ExternalLinkage; | 
| Douglas Gregor | d85b5b9 | 2009-11-25 22:24:25 +0000 | [diff] [blame] | 283 |  | 
| Douglas Gregor | 0b6bc8b | 2010-02-03 09:33:45 +0000 | [diff] [blame] | 284 |   return NoLinkage; | 
| Douglas Gregor | d85b5b9 | 2009-11-25 22:24:25 +0000 | [diff] [blame] | 285 | } | 
 | 286 |  | 
| Douglas Gregor | 0b6bc8b | 2010-02-03 09:33:45 +0000 | [diff] [blame] | 287 | Linkage NamedDecl::getLinkage() const { | 
| Ted Kremenek | becc308 | 2010-04-20 23:15:35 +0000 | [diff] [blame] | 288 |  | 
 | 289 |   // Objective-C: treat all Objective-C declarations as having external | 
 | 290 |   // linkage. | 
 | 291 |   switch (getKind()) { | 
 | 292 |     default: | 
 | 293 |       break; | 
 | 294 |     case Decl::ObjCAtDefsField: | 
 | 295 |     case Decl::ObjCCategory: | 
 | 296 |     case Decl::ObjCCategoryImpl: | 
 | 297 |     case Decl::ObjCClass: | 
 | 298 |     case Decl::ObjCCompatibleAlias: | 
| Ted Kremenek | becc308 | 2010-04-20 23:15:35 +0000 | [diff] [blame] | 299 |     case Decl::ObjCForwardProtocol: | 
 | 300 |     case Decl::ObjCImplementation: | 
 | 301 |     case Decl::ObjCInterface: | 
 | 302 |     case Decl::ObjCIvar: | 
 | 303 |     case Decl::ObjCMethod: | 
 | 304 |     case Decl::ObjCProperty: | 
 | 305 |     case Decl::ObjCPropertyImpl: | 
 | 306 |     case Decl::ObjCProtocol: | 
 | 307 |       return ExternalLinkage; | 
 | 308 |   } | 
 | 309 |  | 
| Douglas Gregor | d85b5b9 | 2009-11-25 22:24:25 +0000 | [diff] [blame] | 310 |   // Handle linkage for namespace-scope names. | 
 | 311 |   if (getDeclContext()->getLookupContext()->isFileContext()) | 
 | 312 |     if (Linkage L = getLinkageForNamespaceScopeDecl(this)) | 
 | 313 |       return L; | 
 | 314 |    | 
 | 315 |   // C++ [basic.link]p5: | 
 | 316 |   //   In addition, a member function, static data member, a named | 
 | 317 |   //   class or enumeration of class scope, or an unnamed class or | 
 | 318 |   //   enumeration defined in a class-scope typedef declaration such | 
 | 319 |   //   that the class or enumeration has the typedef name for linkage | 
 | 320 |   //   purposes (7.1.3), has external linkage if the name of the class | 
 | 321 |   //   has external linkage. | 
 | 322 |   if (getDeclContext()->isRecord() && | 
 | 323 |       (isa<CXXMethodDecl>(this) || isa<VarDecl>(this) || | 
 | 324 |        (isa<TagDecl>(this) && | 
| Douglas Gregor | 0b6bc8b | 2010-02-03 09:33:45 +0000 | [diff] [blame] | 325 |         (getDeclName() || cast<TagDecl>(this)->getTypedefForAnonDecl())))) { | 
 | 326 |     Linkage L = cast<RecordDecl>(getDeclContext())->getLinkage(); | 
 | 327 |     if (isExternalLinkage(L)) | 
 | 328 |       return L; | 
 | 329 |   } | 
| Douglas Gregor | d85b5b9 | 2009-11-25 22:24:25 +0000 | [diff] [blame] | 330 |  | 
 | 331 |   // C++ [basic.link]p6: | 
 | 332 |   //   The name of a function declared in block scope and the name of | 
 | 333 |   //   an object declared by a block scope extern declaration have | 
 | 334 |   //   linkage. If there is a visible declaration of an entity with | 
 | 335 |   //   linkage having the same name and type, ignoring entities | 
 | 336 |   //   declared outside the innermost enclosing namespace scope, the | 
 | 337 |   //   block scope declaration declares that same entity and receives | 
 | 338 |   //   the linkage of the previous declaration. If there is more than | 
 | 339 |   //   one such matching entity, the program is ill-formed. Otherwise, | 
 | 340 |   //   if no matching entity is found, the block scope entity receives | 
 | 341 |   //   external linkage. | 
 | 342 |   if (getLexicalDeclContext()->isFunctionOrMethod()) { | 
 | 343 |     if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(this)) { | 
 | 344 |       if (Function->getPreviousDeclaration()) | 
 | 345 |         if (Linkage L = Function->getPreviousDeclaration()->getLinkage()) | 
 | 346 |           return L; | 
 | 347 |  | 
| Douglas Gregor | 0b6bc8b | 2010-02-03 09:33:45 +0000 | [diff] [blame] | 348 |       if (Function->isInAnonymousNamespace()) | 
 | 349 |         return UniqueExternalLinkage; | 
 | 350 |  | 
| Douglas Gregor | d85b5b9 | 2009-11-25 22:24:25 +0000 | [diff] [blame] | 351 |       return ExternalLinkage; | 
 | 352 |     } | 
 | 353 |  | 
 | 354 |     if (const VarDecl *Var = dyn_cast<VarDecl>(this)) | 
 | 355 |       if (Var->getStorageClass() == VarDecl::Extern || | 
 | 356 |           Var->getStorageClass() == VarDecl::PrivateExtern) { | 
 | 357 |         if (Var->getPreviousDeclaration()) | 
 | 358 |           if (Linkage L = Var->getPreviousDeclaration()->getLinkage()) | 
 | 359 |             return L; | 
 | 360 |  | 
| Douglas Gregor | 0b6bc8b | 2010-02-03 09:33:45 +0000 | [diff] [blame] | 361 |         if (Var->isInAnonymousNamespace()) | 
 | 362 |           return UniqueExternalLinkage; | 
 | 363 |  | 
| Douglas Gregor | d85b5b9 | 2009-11-25 22:24:25 +0000 | [diff] [blame] | 364 |         return ExternalLinkage; | 
 | 365 |       } | 
 | 366 |   } | 
 | 367 |  | 
 | 368 |   // C++ [basic.link]p6: | 
 | 369 |   //   Names not covered by these rules have no linkage. | 
 | 370 |   return NoLinkage; | 
| Douglas Gregor | 0b6bc8b | 2010-02-03 09:33:45 +0000 | [diff] [blame] | 371 |   } | 
| Douglas Gregor | d85b5b9 | 2009-11-25 22:24:25 +0000 | [diff] [blame] | 372 |  | 
| Douglas Gregor | 47b9a1c | 2009-02-04 17:27:36 +0000 | [diff] [blame] | 373 | std::string NamedDecl::getQualifiedNameAsString() const { | 
| Anders Carlsson | 3a082d8 | 2009-09-08 18:24:21 +0000 | [diff] [blame] | 374 |   return getQualifiedNameAsString(getASTContext().getLangOptions()); | 
 | 375 | } | 
 | 376 |  | 
 | 377 | std::string NamedDecl::getQualifiedNameAsString(const PrintingPolicy &P) const { | 
| Douglas Gregor | 47b9a1c | 2009-02-04 17:27:36 +0000 | [diff] [blame] | 378 |   const DeclContext *Ctx = getDeclContext(); | 
 | 379 |  | 
 | 380 |   if (Ctx->isFunctionOrMethod()) | 
 | 381 |     return getNameAsString(); | 
 | 382 |  | 
| Benjamin Kramer | 68eebbb | 2010-04-28 14:33:51 +0000 | [diff] [blame] | 383 |   typedef llvm::SmallVector<const DeclContext *, 8> ContextsTy; | 
 | 384 |   ContextsTy Contexts; | 
 | 385 |  | 
 | 386 |   // Collect contexts. | 
 | 387 |   while (Ctx && isa<NamedDecl>(Ctx)) { | 
 | 388 |     Contexts.push_back(Ctx); | 
 | 389 |     Ctx = Ctx->getParent(); | 
 | 390 |   }; | 
 | 391 |  | 
 | 392 |   std::string QualName; | 
 | 393 |   llvm::raw_string_ostream OS(QualName); | 
 | 394 |  | 
 | 395 |   for (ContextsTy::reverse_iterator I = Contexts.rbegin(), E = Contexts.rend(); | 
 | 396 |        I != E; ++I) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 397 |     if (const ClassTemplateSpecializationDecl *Spec | 
| Benjamin Kramer | 68eebbb | 2010-04-28 14:33:51 +0000 | [diff] [blame] | 398 |           = dyn_cast<ClassTemplateSpecializationDecl>(*I)) { | 
| Douglas Gregor | f3e7ce4 | 2009-05-18 17:01:57 +0000 | [diff] [blame] | 399 |       const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); | 
 | 400 |       std::string TemplateArgsStr | 
 | 401 |         = TemplateSpecializationType::PrintTemplateArgumentList( | 
 | 402 |                                            TemplateArgs.getFlatArgumentList(), | 
| Douglas Gregor | d249e1d1f | 2009-05-29 20:38:28 +0000 | [diff] [blame] | 403 |                                            TemplateArgs.flat_size(), | 
| Anders Carlsson | 3a082d8 | 2009-09-08 18:24:21 +0000 | [diff] [blame] | 404 |                                            P); | 
| Benjamin Kramer | 68eebbb | 2010-04-28 14:33:51 +0000 | [diff] [blame] | 405 |       OS << Spec->getName() << TemplateArgsStr; | 
 | 406 |     } else if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(*I)) { | 
| Sam Weinig | 6be1120 | 2009-12-24 23:15:03 +0000 | [diff] [blame] | 407 |       if (ND->isAnonymousNamespace()) | 
| Benjamin Kramer | 68eebbb | 2010-04-28 14:33:51 +0000 | [diff] [blame] | 408 |         OS << "<anonymous namespace>"; | 
| Sam Weinig | 6be1120 | 2009-12-24 23:15:03 +0000 | [diff] [blame] | 409 |       else | 
| Benjamin Kramer | 68eebbb | 2010-04-28 14:33:51 +0000 | [diff] [blame] | 410 |         OS << ND; | 
 | 411 |     } else if (const RecordDecl *RD = dyn_cast<RecordDecl>(*I)) { | 
 | 412 |       if (!RD->getIdentifier()) | 
 | 413 |         OS << "<anonymous " << RD->getKindName() << '>'; | 
 | 414 |       else | 
 | 415 |         OS << RD; | 
 | 416 |     } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) { | 
| Sam Weinig | 3521d01 | 2009-12-28 03:19:38 +0000 | [diff] [blame] | 417 |       const FunctionProtoType *FT = 0; | 
 | 418 |       if (FD->hasWrittenPrototype()) | 
 | 419 |         FT = dyn_cast<FunctionProtoType>(FD->getType()->getAs<FunctionType>()); | 
 | 420 |  | 
| Benjamin Kramer | 68eebbb | 2010-04-28 14:33:51 +0000 | [diff] [blame] | 421 |       OS << FD << '('; | 
| Sam Weinig | 3521d01 | 2009-12-28 03:19:38 +0000 | [diff] [blame] | 422 |       if (FT) { | 
| Sam Weinig | 3521d01 | 2009-12-28 03:19:38 +0000 | [diff] [blame] | 423 |         unsigned NumParams = FD->getNumParams(); | 
 | 424 |         for (unsigned i = 0; i < NumParams; ++i) { | 
 | 425 |           if (i) | 
| Benjamin Kramer | 68eebbb | 2010-04-28 14:33:51 +0000 | [diff] [blame] | 426 |             OS << ", "; | 
| Sam Weinig | 3521d01 | 2009-12-28 03:19:38 +0000 | [diff] [blame] | 427 |           std::string Param; | 
 | 428 |           FD->getParamDecl(i)->getType().getAsStringInternal(Param, P); | 
| Benjamin Kramer | 68eebbb | 2010-04-28 14:33:51 +0000 | [diff] [blame] | 429 |           OS << Param; | 
| Sam Weinig | 3521d01 | 2009-12-28 03:19:38 +0000 | [diff] [blame] | 430 |         } | 
 | 431 |  | 
 | 432 |         if (FT->isVariadic()) { | 
 | 433 |           if (NumParams > 0) | 
| Benjamin Kramer | 68eebbb | 2010-04-28 14:33:51 +0000 | [diff] [blame] | 434 |             OS << ", "; | 
 | 435 |           OS << "..."; | 
| Sam Weinig | 3521d01 | 2009-12-28 03:19:38 +0000 | [diff] [blame] | 436 |         } | 
 | 437 |       } | 
| Benjamin Kramer | 68eebbb | 2010-04-28 14:33:51 +0000 | [diff] [blame] | 438 |       OS << ')'; | 
 | 439 |     } else { | 
 | 440 |       OS << cast<NamedDecl>(*I); | 
 | 441 |     } | 
 | 442 |     OS << "::"; | 
| Douglas Gregor | 47b9a1c | 2009-02-04 17:27:36 +0000 | [diff] [blame] | 443 |   } | 
 | 444 |  | 
| John McCall | 8472af4 | 2010-03-16 21:48:18 +0000 | [diff] [blame] | 445 |   if (getDeclName()) | 
| Benjamin Kramer | 68eebbb | 2010-04-28 14:33:51 +0000 | [diff] [blame] | 446 |     OS << this; | 
| John McCall | 8472af4 | 2010-03-16 21:48:18 +0000 | [diff] [blame] | 447 |   else | 
| Benjamin Kramer | 68eebbb | 2010-04-28 14:33:51 +0000 | [diff] [blame] | 448 |     OS << "<anonymous>"; | 
| Douglas Gregor | 47b9a1c | 2009-02-04 17:27:36 +0000 | [diff] [blame] | 449 |  | 
| Benjamin Kramer | 68eebbb | 2010-04-28 14:33:51 +0000 | [diff] [blame] | 450 |   return OS.str(); | 
| Douglas Gregor | 47b9a1c | 2009-02-04 17:27:36 +0000 | [diff] [blame] | 451 | } | 
 | 452 |  | 
| Douglas Gregor | 4afa39d | 2009-01-20 01:17:11 +0000 | [diff] [blame] | 453 | bool NamedDecl::declarationReplaces(NamedDecl *OldD) const { | 
| Douglas Gregor | 6ed40e3 | 2008-12-23 21:05:05 +0000 | [diff] [blame] | 454 |   assert(getDeclName() == OldD->getDeclName() && "Declaration name mismatch"); | 
 | 455 |  | 
| Douglas Gregor | 2a3009a | 2009-02-03 19:21:40 +0000 | [diff] [blame] | 456 |   // UsingDirectiveDecl's are not really NamedDecl's, and all have same name. | 
 | 457 |   // We want to keep it, unless it nominates same namespace. | 
 | 458 |   if (getKind() == Decl::UsingDirective) { | 
 | 459 |     return cast<UsingDirectiveDecl>(this)->getNominatedNamespace() == | 
 | 460 |            cast<UsingDirectiveDecl>(OldD)->getNominatedNamespace(); | 
 | 461 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 462 |  | 
| Douglas Gregor | 6ed40e3 | 2008-12-23 21:05:05 +0000 | [diff] [blame] | 463 |   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(this)) | 
 | 464 |     // For function declarations, we keep track of redeclarations. | 
 | 465 |     return FD->getPreviousDeclaration() == OldD; | 
 | 466 |  | 
| Douglas Gregor | e53060f | 2009-06-25 22:08:12 +0000 | [diff] [blame] | 467 |   // For function templates, the underlying function declarations are linked. | 
 | 468 |   if (const FunctionTemplateDecl *FunctionTemplate | 
 | 469 |         = dyn_cast<FunctionTemplateDecl>(this)) | 
 | 470 |     if (const FunctionTemplateDecl *OldFunctionTemplate | 
 | 471 |           = dyn_cast<FunctionTemplateDecl>(OldD)) | 
 | 472 |       return FunctionTemplate->getTemplatedDecl() | 
 | 473 |                ->declarationReplaces(OldFunctionTemplate->getTemplatedDecl()); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 474 |  | 
| Steve Naroff | 0de21fd | 2009-02-22 19:35:57 +0000 | [diff] [blame] | 475 |   // For method declarations, we keep track of redeclarations. | 
 | 476 |   if (isa<ObjCMethodDecl>(this)) | 
 | 477 |     return false; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 478 |  | 
| John McCall | f36e02d | 2009-10-09 21:13:30 +0000 | [diff] [blame] | 479 |   if (isa<ObjCInterfaceDecl>(this) && isa<ObjCCompatibleAliasDecl>(OldD)) | 
 | 480 |     return true; | 
 | 481 |  | 
| John McCall | 9488ea1 | 2009-11-17 05:59:44 +0000 | [diff] [blame] | 482 |   if (isa<UsingShadowDecl>(this) && isa<UsingShadowDecl>(OldD)) | 
 | 483 |     return cast<UsingShadowDecl>(this)->getTargetDecl() == | 
 | 484 |            cast<UsingShadowDecl>(OldD)->getTargetDecl(); | 
 | 485 |  | 
| Douglas Gregor | 6ed40e3 | 2008-12-23 21:05:05 +0000 | [diff] [blame] | 486 |   // For non-function declarations, if the declarations are of the | 
 | 487 |   // same kind then this must be a redeclaration, or semantic analysis | 
 | 488 |   // would not have given us the new declaration. | 
 | 489 |   return this->getKind() == OldD->getKind(); | 
 | 490 | } | 
 | 491 |  | 
| Douglas Gregor | d6f7e9d | 2009-02-24 20:03:32 +0000 | [diff] [blame] | 492 | bool NamedDecl::hasLinkage() const { | 
| Douglas Gregor | d85b5b9 | 2009-11-25 22:24:25 +0000 | [diff] [blame] | 493 |   return getLinkage() != NoLinkage; | 
| Douglas Gregor | d6f7e9d | 2009-02-24 20:03:32 +0000 | [diff] [blame] | 494 | } | 
| Douglas Gregor | 4afa39d | 2009-01-20 01:17:11 +0000 | [diff] [blame] | 495 |  | 
| Anders Carlsson | e136e0e | 2009-06-26 06:29:23 +0000 | [diff] [blame] | 496 | NamedDecl *NamedDecl::getUnderlyingDecl() { | 
 | 497 |   NamedDecl *ND = this; | 
 | 498 |   while (true) { | 
| John McCall | 9488ea1 | 2009-11-17 05:59:44 +0000 | [diff] [blame] | 499 |     if (UsingShadowDecl *UD = dyn_cast<UsingShadowDecl>(ND)) | 
| Anders Carlsson | e136e0e | 2009-06-26 06:29:23 +0000 | [diff] [blame] | 500 |       ND = UD->getTargetDecl(); | 
 | 501 |     else if (ObjCCompatibleAliasDecl *AD | 
 | 502 |               = dyn_cast<ObjCCompatibleAliasDecl>(ND)) | 
 | 503 |       return AD->getClassInterface(); | 
 | 504 |     else | 
 | 505 |       return ND; | 
 | 506 |   } | 
 | 507 | } | 
 | 508 |  | 
| John McCall | 161755a | 2010-04-06 21:38:20 +0000 | [diff] [blame] | 509 | bool NamedDecl::isCXXInstanceMember() const { | 
 | 510 |   assert(isCXXClassMember() && | 
 | 511 |          "checking whether non-member is instance member"); | 
 | 512 |  | 
 | 513 |   const NamedDecl *D = this; | 
 | 514 |   if (isa<UsingShadowDecl>(D)) | 
 | 515 |     D = cast<UsingShadowDecl>(D)->getTargetDecl(); | 
 | 516 |  | 
 | 517 |   if (isa<FieldDecl>(D)) | 
 | 518 |     return true; | 
 | 519 |   if (isa<CXXMethodDecl>(D)) | 
 | 520 |     return cast<CXXMethodDecl>(D)->isInstance(); | 
 | 521 |   if (isa<FunctionTemplateDecl>(D)) | 
 | 522 |     return cast<CXXMethodDecl>(cast<FunctionTemplateDecl>(D) | 
 | 523 |                                  ->getTemplatedDecl())->isInstance(); | 
 | 524 |   return false; | 
 | 525 | } | 
 | 526 |  | 
| Argyrios Kyrtzidis | 5239304 | 2008-11-09 23:41:00 +0000 | [diff] [blame] | 527 | //===----------------------------------------------------------------------===// | 
| Argyrios Kyrtzidis | a5d8200 | 2009-08-21 00:31:54 +0000 | [diff] [blame] | 528 | // DeclaratorDecl Implementation | 
 | 529 | //===----------------------------------------------------------------------===// | 
 | 530 |  | 
| John McCall | b621766 | 2010-03-15 10:12:16 +0000 | [diff] [blame] | 531 | DeclaratorDecl::~DeclaratorDecl() {} | 
 | 532 | void DeclaratorDecl::Destroy(ASTContext &C) { | 
 | 533 |   if (hasExtInfo()) | 
 | 534 |     C.Deallocate(getExtInfo()); | 
 | 535 |   ValueDecl::Destroy(C); | 
 | 536 | } | 
 | 537 |  | 
| Argyrios Kyrtzidis | a5d8200 | 2009-08-21 00:31:54 +0000 | [diff] [blame] | 538 | SourceLocation DeclaratorDecl::getTypeSpecStartLoc() const { | 
| John McCall | 51bd803 | 2009-10-18 01:05:36 +0000 | [diff] [blame] | 539 |   if (DeclInfo) { | 
| John McCall | b621766 | 2010-03-15 10:12:16 +0000 | [diff] [blame] | 540 |     TypeLoc TL = getTypeSourceInfo()->getTypeLoc(); | 
| John McCall | 51bd803 | 2009-10-18 01:05:36 +0000 | [diff] [blame] | 541 |     while (true) { | 
 | 542 |       TypeLoc NextTL = TL.getNextTypeLoc(); | 
 | 543 |       if (!NextTL) | 
 | 544 |         return TL.getSourceRange().getBegin(); | 
 | 545 |       TL = NextTL; | 
 | 546 |     } | 
 | 547 |   } | 
| Argyrios Kyrtzidis | a5d8200 | 2009-08-21 00:31:54 +0000 | [diff] [blame] | 548 |   return SourceLocation(); | 
 | 549 | } | 
 | 550 |  | 
| John McCall | b621766 | 2010-03-15 10:12:16 +0000 | [diff] [blame] | 551 | void DeclaratorDecl::setQualifierInfo(NestedNameSpecifier *Qualifier, | 
 | 552 |                                       SourceRange QualifierRange) { | 
 | 553 |   if (Qualifier) { | 
 | 554 |     // Make sure the extended decl info is allocated. | 
 | 555 |     if (!hasExtInfo()) { | 
 | 556 |       // Save (non-extended) type source info pointer. | 
 | 557 |       TypeSourceInfo *savedTInfo = DeclInfo.get<TypeSourceInfo*>(); | 
 | 558 |       // Allocate external info struct. | 
 | 559 |       DeclInfo = new (getASTContext()) ExtInfo; | 
 | 560 |       // Restore savedTInfo into (extended) decl info. | 
 | 561 |       getExtInfo()->TInfo = savedTInfo; | 
 | 562 |     } | 
 | 563 |     // Set qualifier info. | 
 | 564 |     getExtInfo()->NNS = Qualifier; | 
 | 565 |     getExtInfo()->NNSRange = QualifierRange; | 
 | 566 |   } | 
 | 567 |   else { | 
 | 568 |     // Here Qualifier == 0, i.e., we are removing the qualifier (if any). | 
 | 569 |     assert(QualifierRange.isInvalid()); | 
 | 570 |     if (hasExtInfo()) { | 
 | 571 |       // Save type source info pointer. | 
 | 572 |       TypeSourceInfo *savedTInfo = getExtInfo()->TInfo; | 
 | 573 |       // Deallocate the extended decl info. | 
 | 574 |       getASTContext().Deallocate(getExtInfo()); | 
 | 575 |       // Restore savedTInfo into (non-extended) decl info. | 
 | 576 |       DeclInfo = savedTInfo; | 
 | 577 |     } | 
 | 578 |   } | 
 | 579 | } | 
 | 580 |  | 
| Argyrios Kyrtzidis | a5d8200 | 2009-08-21 00:31:54 +0000 | [diff] [blame] | 581 | //===----------------------------------------------------------------------===// | 
| Nuno Lopes | 99f06ba | 2008-12-17 23:39:55 +0000 | [diff] [blame] | 582 | // VarDecl Implementation | 
 | 583 | //===----------------------------------------------------------------------===// | 
 | 584 |  | 
| Sebastian Redl | 7783bfc | 2010-01-26 22:01:41 +0000 | [diff] [blame] | 585 | const char *VarDecl::getStorageClassSpecifierString(StorageClass SC) { | 
 | 586 |   switch (SC) { | 
 | 587 |   case VarDecl::None:          break; | 
 | 588 |   case VarDecl::Auto:          return "auto"; break; | 
 | 589 |   case VarDecl::Extern:        return "extern"; break; | 
 | 590 |   case VarDecl::PrivateExtern: return "__private_extern__"; break; | 
 | 591 |   case VarDecl::Register:      return "register"; break; | 
 | 592 |   case VarDecl::Static:        return "static"; break; | 
 | 593 |   } | 
 | 594 |  | 
 | 595 |   assert(0 && "Invalid storage class"); | 
 | 596 |   return 0; | 
 | 597 | } | 
 | 598 |  | 
| Douglas Gregor | 4afa39d | 2009-01-20 01:17:11 +0000 | [diff] [blame] | 599 | VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, | 
| John McCall | a93c934 | 2009-12-07 02:54:59 +0000 | [diff] [blame] | 600 |                          IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, | 
| Douglas Gregor | 16573fa | 2010-04-19 22:54:31 +0000 | [diff] [blame] | 601 |                          StorageClass S, StorageClass SCAsWritten) { | 
 | 602 |   return new (C) VarDecl(Var, DC, L, Id, T, TInfo, S, SCAsWritten); | 
| Nuno Lopes | 99f06ba | 2008-12-17 23:39:55 +0000 | [diff] [blame] | 603 | } | 
 | 604 |  | 
 | 605 | void VarDecl::Destroy(ASTContext& C) { | 
| Sebastian Redl | df2d3cf | 2009-02-05 15:12:41 +0000 | [diff] [blame] | 606 |   Expr *Init = getInit(); | 
| Douglas Gregor | 78d1583 | 2009-05-26 18:54:04 +0000 | [diff] [blame] | 607 |   if (Init) { | 
| Sebastian Redl | df2d3cf | 2009-02-05 15:12:41 +0000 | [diff] [blame] | 608 |     Init->Destroy(C); | 
| Douglas Gregor | 78d1583 | 2009-05-26 18:54:04 +0000 | [diff] [blame] | 609 |     if (EvaluatedStmt *Eval = this->Init.dyn_cast<EvaluatedStmt *>()) { | 
 | 610 |       Eval->~EvaluatedStmt(); | 
 | 611 |       C.Deallocate(Eval); | 
 | 612 |     } | 
 | 613 |   } | 
| Nuno Lopes | 99f06ba | 2008-12-17 23:39:55 +0000 | [diff] [blame] | 614 |   this->~VarDecl(); | 
| John McCall | b621766 | 2010-03-15 10:12:16 +0000 | [diff] [blame] | 615 |   DeclaratorDecl::Destroy(C); | 
| Nuno Lopes | 99f06ba | 2008-12-17 23:39:55 +0000 | [diff] [blame] | 616 | } | 
 | 617 |  | 
 | 618 | VarDecl::~VarDecl() { | 
| Nuno Lopes | 99f06ba | 2008-12-17 23:39:55 +0000 | [diff] [blame] | 619 | } | 
 | 620 |  | 
| Argyrios Kyrtzidis | 55d608c | 2009-06-20 08:09:14 +0000 | [diff] [blame] | 621 | SourceRange VarDecl::getSourceRange() const { | 
| Douglas Gregor | 33e9abd | 2010-01-22 19:49:59 +0000 | [diff] [blame] | 622 |   SourceLocation Start = getTypeSpecStartLoc(); | 
 | 623 |   if (Start.isInvalid()) | 
 | 624 |     Start = getLocation(); | 
 | 625 |    | 
| Argyrios Kyrtzidis | 55d608c | 2009-06-20 08:09:14 +0000 | [diff] [blame] | 626 |   if (getInit()) | 
| Douglas Gregor | 33e9abd | 2010-01-22 19:49:59 +0000 | [diff] [blame] | 627 |     return SourceRange(Start, getInit()->getLocEnd()); | 
 | 628 |   return SourceRange(Start, getLocation()); | 
| Argyrios Kyrtzidis | 55d608c | 2009-06-20 08:09:14 +0000 | [diff] [blame] | 629 | } | 
 | 630 |  | 
| Sebastian Redl | 7783bfc | 2010-01-26 22:01:41 +0000 | [diff] [blame] | 631 | bool VarDecl::isExternC() const { | 
 | 632 |   ASTContext &Context = getASTContext(); | 
 | 633 |   if (!Context.getLangOptions().CPlusPlus) | 
 | 634 |     return (getDeclContext()->isTranslationUnit() && | 
 | 635 |             getStorageClass() != Static) || | 
 | 636 |       (getDeclContext()->isFunctionOrMethod() && hasExternalStorage()); | 
 | 637 |  | 
 | 638 |   for (const DeclContext *DC = getDeclContext(); !DC->isTranslationUnit(); | 
 | 639 |        DC = DC->getParent()) { | 
 | 640 |     if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC))  { | 
 | 641 |       if (Linkage->getLanguage() == LinkageSpecDecl::lang_c) | 
 | 642 |         return getStorageClass() != Static; | 
 | 643 |  | 
 | 644 |       break; | 
 | 645 |     } | 
 | 646 |  | 
 | 647 |     if (DC->isFunctionOrMethod()) | 
 | 648 |       return false; | 
 | 649 |   } | 
 | 650 |  | 
 | 651 |   return false; | 
 | 652 | } | 
 | 653 |  | 
 | 654 | VarDecl *VarDecl::getCanonicalDecl() { | 
 | 655 |   return getFirstDeclaration(); | 
 | 656 | } | 
 | 657 |  | 
| Sebastian Redl | e9d12b6 | 2010-01-31 22:27:38 +0000 | [diff] [blame] | 658 | VarDecl::DefinitionKind VarDecl::isThisDeclarationADefinition() const { | 
 | 659 |   // C++ [basic.def]p2: | 
 | 660 |   //   A declaration is a definition unless [...] it contains the 'extern' | 
 | 661 |   //   specifier or a linkage-specification and neither an initializer [...], | 
 | 662 |   //   it declares a static data member in a class declaration [...]. | 
 | 663 |   // C++ [temp.expl.spec]p15: | 
 | 664 |   //   An explicit specialization of a static data member of a template is a | 
 | 665 |   //   definition if the declaration includes an initializer; otherwise, it is | 
 | 666 |   //   a declaration. | 
 | 667 |   if (isStaticDataMember()) { | 
 | 668 |     if (isOutOfLine() && (hasInit() || | 
 | 669 |           getTemplateSpecializationKind() != TSK_ExplicitSpecialization)) | 
 | 670 |       return Definition; | 
 | 671 |     else | 
 | 672 |       return DeclarationOnly; | 
 | 673 |   } | 
 | 674 |   // C99 6.7p5: | 
 | 675 |   //   A definition of an identifier is a declaration for that identifier that | 
 | 676 |   //   [...] causes storage to be reserved for that object. | 
 | 677 |   // Note: that applies for all non-file-scope objects. | 
 | 678 |   // C99 6.9.2p1: | 
 | 679 |   //   If the declaration of an identifier for an object has file scope and an | 
 | 680 |   //   initializer, the declaration is an external definition for the identifier | 
 | 681 |   if (hasInit()) | 
 | 682 |     return Definition; | 
 | 683 |   // AST for 'extern "C" int foo;' is annotated with 'extern'. | 
 | 684 |   if (hasExternalStorage()) | 
 | 685 |     return DeclarationOnly; | 
 | 686 |  | 
 | 687 |   // C99 6.9.2p2: | 
 | 688 |   //   A declaration of an object that has file scope without an initializer, | 
 | 689 |   //   and without a storage class specifier or the scs 'static', constitutes | 
 | 690 |   //   a tentative definition. | 
 | 691 |   // No such thing in C++. | 
 | 692 |   if (!getASTContext().getLangOptions().CPlusPlus && isFileVarDecl()) | 
 | 693 |     return TentativeDefinition; | 
 | 694 |  | 
 | 695 |   // What's left is (in C, block-scope) declarations without initializers or | 
 | 696 |   // external storage. These are definitions. | 
 | 697 |   return Definition; | 
 | 698 | } | 
 | 699 |  | 
| Sebastian Redl | e9d12b6 | 2010-01-31 22:27:38 +0000 | [diff] [blame] | 700 | VarDecl *VarDecl::getActingDefinition() { | 
 | 701 |   DefinitionKind Kind = isThisDeclarationADefinition(); | 
 | 702 |   if (Kind != TentativeDefinition) | 
 | 703 |     return 0; | 
 | 704 |  | 
 | 705 |   VarDecl *LastTentative = false; | 
 | 706 |   VarDecl *First = getFirstDeclaration(); | 
 | 707 |   for (redecl_iterator I = First->redecls_begin(), E = First->redecls_end(); | 
 | 708 |        I != E; ++I) { | 
 | 709 |     Kind = (*I)->isThisDeclarationADefinition(); | 
 | 710 |     if (Kind == Definition) | 
 | 711 |       return 0; | 
 | 712 |     else if (Kind == TentativeDefinition) | 
 | 713 |       LastTentative = *I; | 
 | 714 |   } | 
 | 715 |   return LastTentative; | 
 | 716 | } | 
 | 717 |  | 
 | 718 | bool VarDecl::isTentativeDefinitionNow() const { | 
 | 719 |   DefinitionKind Kind = isThisDeclarationADefinition(); | 
 | 720 |   if (Kind != TentativeDefinition) | 
 | 721 |     return false; | 
 | 722 |  | 
 | 723 |   for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) { | 
 | 724 |     if ((*I)->isThisDeclarationADefinition() == Definition) | 
 | 725 |       return false; | 
 | 726 |   } | 
| Sebastian Redl | 31310a2 | 2010-02-01 20:16:42 +0000 | [diff] [blame] | 727 |   return true; | 
| Sebastian Redl | e9d12b6 | 2010-01-31 22:27:38 +0000 | [diff] [blame] | 728 | } | 
 | 729 |  | 
| Sebastian Redl | 31310a2 | 2010-02-01 20:16:42 +0000 | [diff] [blame] | 730 | VarDecl *VarDecl::getDefinition() { | 
| Sebastian Redl | e2c52d2 | 2010-02-02 17:55:12 +0000 | [diff] [blame] | 731 |   VarDecl *First = getFirstDeclaration(); | 
 | 732 |   for (redecl_iterator I = First->redecls_begin(), E = First->redecls_end(); | 
 | 733 |        I != E; ++I) { | 
| Sebastian Redl | 31310a2 | 2010-02-01 20:16:42 +0000 | [diff] [blame] | 734 |     if ((*I)->isThisDeclarationADefinition() == Definition) | 
 | 735 |       return *I; | 
 | 736 |   } | 
 | 737 |   return 0; | 
 | 738 | } | 
 | 739 |  | 
 | 740 | const Expr *VarDecl::getAnyInitializer(const VarDecl *&D) const { | 
| Sebastian Redl | 7783bfc | 2010-01-26 22:01:41 +0000 | [diff] [blame] | 741 |   redecl_iterator I = redecls_begin(), E = redecls_end(); | 
 | 742 |   while (I != E && !I->getInit()) | 
 | 743 |     ++I; | 
 | 744 |  | 
 | 745 |   if (I != E) { | 
| Sebastian Redl | 31310a2 | 2010-02-01 20:16:42 +0000 | [diff] [blame] | 746 |     D = *I; | 
| Sebastian Redl | 7783bfc | 2010-01-26 22:01:41 +0000 | [diff] [blame] | 747 |     return I->getInit(); | 
 | 748 |   } | 
 | 749 |   return 0; | 
 | 750 | } | 
 | 751 |  | 
| Douglas Gregor | 1028c9f | 2009-10-14 21:29:40 +0000 | [diff] [blame] | 752 | bool VarDecl::isOutOfLine() const { | 
| Douglas Gregor | 1028c9f | 2009-10-14 21:29:40 +0000 | [diff] [blame] | 753 |   if (Decl::isOutOfLine()) | 
 | 754 |     return true; | 
| Chandler Carruth | 8761d68 | 2010-02-21 07:08:09 +0000 | [diff] [blame] | 755 |  | 
 | 756 |   if (!isStaticDataMember()) | 
 | 757 |     return false; | 
 | 758 |  | 
| Douglas Gregor | 1028c9f | 2009-10-14 21:29:40 +0000 | [diff] [blame] | 759 |   // If this static data member was instantiated from a static data member of | 
 | 760 |   // a class template, check whether that static data member was defined  | 
 | 761 |   // out-of-line. | 
 | 762 |   if (VarDecl *VD = getInstantiatedFromStaticDataMember()) | 
 | 763 |     return VD->isOutOfLine(); | 
 | 764 |    | 
 | 765 |   return false; | 
 | 766 | } | 
 | 767 |  | 
| Douglas Gregor | 0d03514 | 2009-10-27 18:42:08 +0000 | [diff] [blame] | 768 | VarDecl *VarDecl::getOutOfLineDefinition() { | 
 | 769 |   if (!isStaticDataMember()) | 
 | 770 |     return 0; | 
 | 771 |    | 
 | 772 |   for (VarDecl::redecl_iterator RD = redecls_begin(), RDEnd = redecls_end(); | 
 | 773 |        RD != RDEnd; ++RD) { | 
 | 774 |     if (RD->getLexicalDeclContext()->isFileContext()) | 
 | 775 |       return *RD; | 
 | 776 |   } | 
 | 777 |    | 
 | 778 |   return 0; | 
 | 779 | } | 
 | 780 |  | 
| Douglas Gregor | 838db38 | 2010-02-11 01:19:42 +0000 | [diff] [blame] | 781 | void VarDecl::setInit(Expr *I) { | 
| Sebastian Redl | 7783bfc | 2010-01-26 22:01:41 +0000 | [diff] [blame] | 782 |   if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>()) { | 
 | 783 |     Eval->~EvaluatedStmt(); | 
| Douglas Gregor | 838db38 | 2010-02-11 01:19:42 +0000 | [diff] [blame] | 784 |     getASTContext().Deallocate(Eval); | 
| Sebastian Redl | 7783bfc | 2010-01-26 22:01:41 +0000 | [diff] [blame] | 785 |   } | 
 | 786 |  | 
 | 787 |   Init = I; | 
 | 788 | } | 
 | 789 |  | 
| Douglas Gregor | 1028c9f | 2009-10-14 21:29:40 +0000 | [diff] [blame] | 790 | VarDecl *VarDecl::getInstantiatedFromStaticDataMember() const { | 
| Douglas Gregor | b3ae4fc | 2009-10-12 20:18:28 +0000 | [diff] [blame] | 791 |   if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo()) | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 792 |     return cast<VarDecl>(MSI->getInstantiatedFrom()); | 
 | 793 |    | 
 | 794 |   return 0; | 
 | 795 | } | 
 | 796 |  | 
| Douglas Gregor | 663b5a0 | 2009-10-14 20:14:33 +0000 | [diff] [blame] | 797 | TemplateSpecializationKind VarDecl::getTemplateSpecializationKind() const { | 
| Sebastian Redl | e9d12b6 | 2010-01-31 22:27:38 +0000 | [diff] [blame] | 798 |   if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo()) | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 799 |     return MSI->getTemplateSpecializationKind(); | 
 | 800 |    | 
 | 801 |   return TSK_Undeclared; | 
 | 802 | } | 
 | 803 |  | 
| Douglas Gregor | 1028c9f | 2009-10-14 21:29:40 +0000 | [diff] [blame] | 804 | MemberSpecializationInfo *VarDecl::getMemberSpecializationInfo() const { | 
| Douglas Gregor | b3ae4fc | 2009-10-12 20:18:28 +0000 | [diff] [blame] | 805 |   return getASTContext().getInstantiatedFromStaticDataMember(this); | 
 | 806 | } | 
 | 807 |  | 
| Douglas Gregor | 0a897e3 | 2009-10-15 17:21:20 +0000 | [diff] [blame] | 808 | void VarDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK, | 
 | 809 |                                          SourceLocation PointOfInstantiation) { | 
| Douglas Gregor | b3ae4fc | 2009-10-12 20:18:28 +0000 | [diff] [blame] | 810 |   MemberSpecializationInfo *MSI = getMemberSpecializationInfo(); | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 811 |   assert(MSI && "Not an instantiated static data member?"); | 
 | 812 |   MSI->setTemplateSpecializationKind(TSK); | 
| Douglas Gregor | 0a897e3 | 2009-10-15 17:21:20 +0000 | [diff] [blame] | 813 |   if (TSK != TSK_ExplicitSpecialization && | 
 | 814 |       PointOfInstantiation.isValid() && | 
 | 815 |       MSI->getPointOfInstantiation().isInvalid()) | 
 | 816 |     MSI->setPointOfInstantiation(PointOfInstantiation); | 
| Douglas Gregor | 7caa682 | 2009-07-24 20:34:43 +0000 | [diff] [blame] | 817 | } | 
 | 818 |  | 
| Sebastian Redl | 7783bfc | 2010-01-26 22:01:41 +0000 | [diff] [blame] | 819 | //===----------------------------------------------------------------------===// | 
 | 820 | // ParmVarDecl Implementation | 
 | 821 | //===----------------------------------------------------------------------===// | 
| Douglas Gregor | 275a369 | 2009-03-10 23:43:53 +0000 | [diff] [blame] | 822 |  | 
| Sebastian Redl | 7783bfc | 2010-01-26 22:01:41 +0000 | [diff] [blame] | 823 | ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC, | 
 | 824 |                                  SourceLocation L, IdentifierInfo *Id, | 
 | 825 |                                  QualType T, TypeSourceInfo *TInfo, | 
| Douglas Gregor | 16573fa | 2010-04-19 22:54:31 +0000 | [diff] [blame] | 826 |                                  StorageClass S, StorageClass SCAsWritten, | 
 | 827 |                                  Expr *DefArg) { | 
 | 828 |   return new (C) ParmVarDecl(ParmVar, DC, L, Id, T, TInfo, | 
 | 829 |                              S, SCAsWritten, DefArg); | 
| Douglas Gregor | 275a369 | 2009-03-10 23:43:53 +0000 | [diff] [blame] | 830 | } | 
 | 831 |  | 
| Sebastian Redl | 7783bfc | 2010-01-26 22:01:41 +0000 | [diff] [blame] | 832 | Expr *ParmVarDecl::getDefaultArg() { | 
 | 833 |   assert(!hasUnparsedDefaultArg() && "Default argument is not yet parsed!"); | 
 | 834 |   assert(!hasUninstantiatedDefaultArg() && | 
 | 835 |          "Default argument is not yet instantiated!"); | 
 | 836 |    | 
 | 837 |   Expr *Arg = getInit(); | 
 | 838 |   if (CXXExprWithTemporaries *E = dyn_cast_or_null<CXXExprWithTemporaries>(Arg)) | 
 | 839 |     return E->getSubExpr(); | 
| Douglas Gregor | 275a369 | 2009-03-10 23:43:53 +0000 | [diff] [blame] | 840 |  | 
| Sebastian Redl | 7783bfc | 2010-01-26 22:01:41 +0000 | [diff] [blame] | 841 |   return Arg; | 
 | 842 | } | 
 | 843 |  | 
 | 844 | unsigned ParmVarDecl::getNumDefaultArgTemporaries() const { | 
 | 845 |   if (const CXXExprWithTemporaries *E =  | 
 | 846 |         dyn_cast<CXXExprWithTemporaries>(getInit())) | 
 | 847 |     return E->getNumTemporaries(); | 
 | 848 |  | 
| Argyrios Kyrtzidis | c37929c | 2009-07-14 03:20:21 +0000 | [diff] [blame] | 849 |   return 0; | 
| Douglas Gregor | 275a369 | 2009-03-10 23:43:53 +0000 | [diff] [blame] | 850 | } | 
 | 851 |  | 
| Sebastian Redl | 7783bfc | 2010-01-26 22:01:41 +0000 | [diff] [blame] | 852 | CXXTemporary *ParmVarDecl::getDefaultArgTemporary(unsigned i) { | 
 | 853 |   assert(getNumDefaultArgTemporaries() &&  | 
 | 854 |          "Default arguments does not have any temporaries!"); | 
 | 855 |  | 
 | 856 |   CXXExprWithTemporaries *E = cast<CXXExprWithTemporaries>(getInit()); | 
 | 857 |   return E->getTemporary(i); | 
 | 858 | } | 
 | 859 |  | 
 | 860 | SourceRange ParmVarDecl::getDefaultArgRange() const { | 
 | 861 |   if (const Expr *E = getInit()) | 
 | 862 |     return E->getSourceRange(); | 
 | 863 |  | 
 | 864 |   if (hasUninstantiatedDefaultArg()) | 
 | 865 |     return getUninstantiatedDefaultArg()->getSourceRange(); | 
 | 866 |  | 
 | 867 |   return SourceRange(); | 
| Argyrios Kyrtzidis | fc7e2a8 | 2009-07-05 22:21:56 +0000 | [diff] [blame] | 868 | } | 
 | 869 |  | 
| Nuno Lopes | 99f06ba | 2008-12-17 23:39:55 +0000 | [diff] [blame] | 870 | //===----------------------------------------------------------------------===// | 
| Chris Lattner | 8a93423 | 2008-03-31 00:36:02 +0000 | [diff] [blame] | 871 | // FunctionDecl Implementation | 
 | 872 | //===----------------------------------------------------------------------===// | 
 | 873 |  | 
| Ted Kremenek | 27f8a28 | 2008-05-20 00:43:19 +0000 | [diff] [blame] | 874 | void FunctionDecl::Destroy(ASTContext& C) { | 
| Douglas Gregor | 250fc9c | 2009-04-18 00:07:54 +0000 | [diff] [blame] | 875 |   if (Body && Body.isOffset()) | 
 | 876 |     Body.get(C.getExternalSource())->Destroy(C); | 
| Ted Kremenek | b65cf41 | 2008-05-20 03:56:00 +0000 | [diff] [blame] | 877 |  | 
 | 878 |   for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I) | 
 | 879 |     (*I)->Destroy(C); | 
| Nuno Lopes | 460b0ac | 2009-01-18 19:57:27 +0000 | [diff] [blame] | 880 |  | 
| Douglas Gregor | 2db3232 | 2009-10-07 23:56:10 +0000 | [diff] [blame] | 881 |   FunctionTemplateSpecializationInfo *FTSInfo | 
 | 882 |     = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>(); | 
 | 883 |   if (FTSInfo) | 
 | 884 |     C.Deallocate(FTSInfo); | 
 | 885 |    | 
 | 886 |   MemberSpecializationInfo *MSInfo | 
 | 887 |     = TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>(); | 
 | 888 |   if (MSInfo) | 
 | 889 |     C.Deallocate(MSInfo); | 
 | 890 |    | 
| Steve Naroff | 3e97049 | 2009-01-27 21:25:57 +0000 | [diff] [blame] | 891 |   C.Deallocate(ParamInfo); | 
| Nuno Lopes | 460b0ac | 2009-01-18 19:57:27 +0000 | [diff] [blame] | 892 |  | 
| John McCall | b621766 | 2010-03-15 10:12:16 +0000 | [diff] [blame] | 893 |   DeclaratorDecl::Destroy(C); | 
| Ted Kremenek | 27f8a28 | 2008-05-20 00:43:19 +0000 | [diff] [blame] | 894 | } | 
 | 895 |  | 
| John McCall | 136a698 | 2009-09-11 06:45:03 +0000 | [diff] [blame] | 896 | void FunctionDecl::getNameForDiagnostic(std::string &S, | 
 | 897 |                                         const PrintingPolicy &Policy, | 
 | 898 |                                         bool Qualified) const { | 
 | 899 |   NamedDecl::getNameForDiagnostic(S, Policy, Qualified); | 
 | 900 |   const TemplateArgumentList *TemplateArgs = getTemplateSpecializationArgs(); | 
 | 901 |   if (TemplateArgs) | 
 | 902 |     S += TemplateSpecializationType::PrintTemplateArgumentList( | 
 | 903 |                                          TemplateArgs->getFlatArgumentList(), | 
 | 904 |                                          TemplateArgs->flat_size(), | 
 | 905 |                                                                Policy); | 
 | 906 |      | 
 | 907 | } | 
| Ted Kremenek | 27f8a28 | 2008-05-20 00:43:19 +0000 | [diff] [blame] | 908 |  | 
| Argyrios Kyrtzidis | 6fb0aee | 2009-06-30 02:35:26 +0000 | [diff] [blame] | 909 | Stmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const { | 
| Argyrios Kyrtzidis | c37929c | 2009-07-14 03:20:21 +0000 | [diff] [blame] | 910 |   for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) { | 
 | 911 |     if (I->Body) { | 
 | 912 |       Definition = *I; | 
 | 913 |       return I->Body.get(getASTContext().getExternalSource()); | 
| Douglas Gregor | f009795 | 2008-04-21 02:02:58 +0000 | [diff] [blame] | 914 |     } | 
 | 915 |   } | 
 | 916 |  | 
 | 917 |   return 0; | 
| Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 918 | } | 
 | 919 |  | 
| Argyrios Kyrtzidis | 55d608c | 2009-06-20 08:09:14 +0000 | [diff] [blame] | 920 | void FunctionDecl::setBody(Stmt *B) { | 
 | 921 |   Body = B; | 
| Argyrios Kyrtzidis | 1a5364e | 2009-06-22 17:13:31 +0000 | [diff] [blame] | 922 |   if (B) | 
| Argyrios Kyrtzidis | 55d608c | 2009-06-20 08:09:14 +0000 | [diff] [blame] | 923 |     EndRangeLoc = B->getLocEnd(); | 
 | 924 | } | 
 | 925 |  | 
| Douglas Gregor | 48a83b5 | 2009-09-12 00:17:51 +0000 | [diff] [blame] | 926 | bool FunctionDecl::isMain() const { | 
 | 927 |   ASTContext &Context = getASTContext(); | 
| John McCall | 07a5c22 | 2009-08-15 02:09:25 +0000 | [diff] [blame] | 928 |   return !Context.getLangOptions().Freestanding && | 
 | 929 |     getDeclContext()->getLookupContext()->isTranslationUnit() && | 
| Douglas Gregor | 04495c8 | 2009-02-24 01:23:02 +0000 | [diff] [blame] | 930 |     getIdentifier() && getIdentifier()->isStr("main"); | 
 | 931 | } | 
 | 932 |  | 
| Douglas Gregor | 48a83b5 | 2009-09-12 00:17:51 +0000 | [diff] [blame] | 933 | bool FunctionDecl::isExternC() const { | 
 | 934 |   ASTContext &Context = getASTContext(); | 
| Douglas Gregor | 6393519 | 2009-03-02 00:19:53 +0000 | [diff] [blame] | 935 |   // In C, any non-static, non-overloadable function has external | 
 | 936 |   // linkage. | 
 | 937 |   if (!Context.getLangOptions().CPlusPlus) | 
| Argyrios Kyrtzidis | 40b598e | 2009-06-30 02:34:44 +0000 | [diff] [blame] | 938 |     return getStorageClass() != Static && !getAttr<OverloadableAttr>(); | 
| Douglas Gregor | 6393519 | 2009-03-02 00:19:53 +0000 | [diff] [blame] | 939 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 940 |   for (const DeclContext *DC = getDeclContext(); !DC->isTranslationUnit(); | 
| Douglas Gregor | 6393519 | 2009-03-02 00:19:53 +0000 | [diff] [blame] | 941 |        DC = DC->getParent()) { | 
 | 942 |     if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC))  { | 
 | 943 |       if (Linkage->getLanguage() == LinkageSpecDecl::lang_c) | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 944 |         return getStorageClass() != Static && | 
| Argyrios Kyrtzidis | 40b598e | 2009-06-30 02:34:44 +0000 | [diff] [blame] | 945 |                !getAttr<OverloadableAttr>(); | 
| Douglas Gregor | 6393519 | 2009-03-02 00:19:53 +0000 | [diff] [blame] | 946 |  | 
 | 947 |       break; | 
 | 948 |     } | 
 | 949 |   } | 
 | 950 |  | 
 | 951 |   return false; | 
 | 952 | } | 
 | 953 |  | 
| Douglas Gregor | 8499f3f | 2009-03-31 16:35:03 +0000 | [diff] [blame] | 954 | bool FunctionDecl::isGlobal() const { | 
 | 955 |   if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(this)) | 
 | 956 |     return Method->isStatic(); | 
 | 957 |  | 
 | 958 |   if (getStorageClass() == Static) | 
 | 959 |     return false; | 
 | 960 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 961 |   for (const DeclContext *DC = getDeclContext(); | 
| Douglas Gregor | 8499f3f | 2009-03-31 16:35:03 +0000 | [diff] [blame] | 962 |        DC->isNamespace(); | 
 | 963 |        DC = DC->getParent()) { | 
 | 964 |     if (const NamespaceDecl *Namespace = cast<NamespaceDecl>(DC)) { | 
 | 965 |       if (!Namespace->getDeclName()) | 
 | 966 |         return false; | 
 | 967 |       break; | 
 | 968 |     } | 
 | 969 |   } | 
 | 970 |  | 
 | 971 |   return true; | 
 | 972 | } | 
 | 973 |  | 
| Sebastian Redl | 7783bfc | 2010-01-26 22:01:41 +0000 | [diff] [blame] | 974 | void | 
 | 975 | FunctionDecl::setPreviousDeclaration(FunctionDecl *PrevDecl) { | 
 | 976 |   redeclarable_base::setPreviousDeclaration(PrevDecl); | 
 | 977 |  | 
 | 978 |   if (FunctionTemplateDecl *FunTmpl = getDescribedFunctionTemplate()) { | 
 | 979 |     FunctionTemplateDecl *PrevFunTmpl | 
 | 980 |       = PrevDecl? PrevDecl->getDescribedFunctionTemplate() : 0; | 
 | 981 |     assert((!PrevDecl || PrevFunTmpl) && "Function/function template mismatch"); | 
 | 982 |     FunTmpl->setPreviousDeclaration(PrevFunTmpl); | 
 | 983 |   } | 
 | 984 | } | 
 | 985 |  | 
 | 986 | const FunctionDecl *FunctionDecl::getCanonicalDecl() const { | 
 | 987 |   return getFirstDeclaration(); | 
 | 988 | } | 
 | 989 |  | 
 | 990 | FunctionDecl *FunctionDecl::getCanonicalDecl() { | 
 | 991 |   return getFirstDeclaration(); | 
 | 992 | } | 
 | 993 |  | 
| Douglas Gregor | 3e41d60 | 2009-02-13 23:20:09 +0000 | [diff] [blame] | 994 | /// \brief Returns a value indicating whether this function | 
 | 995 | /// corresponds to a builtin function. | 
 | 996 | /// | 
 | 997 | /// The function corresponds to a built-in function if it is | 
 | 998 | /// declared at translation scope or within an extern "C" block and | 
 | 999 | /// its name matches with the name of a builtin. The returned value | 
 | 1000 | /// will be 0 for functions that do not correspond to a builtin, a | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1001 | /// value of type \c Builtin::ID if in the target-independent range | 
| Douglas Gregor | 3e41d60 | 2009-02-13 23:20:09 +0000 | [diff] [blame] | 1002 | /// \c [1,Builtin::First), or a target-specific builtin value. | 
| Douglas Gregor | 7814e6d | 2009-09-12 00:22:50 +0000 | [diff] [blame] | 1003 | unsigned FunctionDecl::getBuiltinID() const { | 
 | 1004 |   ASTContext &Context = getASTContext(); | 
| Douglas Gregor | 3c385e5 | 2009-02-14 18:57:46 +0000 | [diff] [blame] | 1005 |   if (!getIdentifier() || !getIdentifier()->getBuiltinID()) | 
 | 1006 |     return 0; | 
 | 1007 |  | 
 | 1008 |   unsigned BuiltinID = getIdentifier()->getBuiltinID(); | 
 | 1009 |   if (!Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) | 
 | 1010 |     return BuiltinID; | 
 | 1011 |  | 
 | 1012 |   // This function has the name of a known C library | 
 | 1013 |   // function. Determine whether it actually refers to the C library | 
 | 1014 |   // function or whether it just has the same name. | 
 | 1015 |  | 
| Douglas Gregor | 9add317 | 2009-02-17 03:23:10 +0000 | [diff] [blame] | 1016 |   // If this is a static function, it's not a builtin. | 
 | 1017 |   if (getStorageClass() == Static) | 
 | 1018 |     return 0; | 
 | 1019 |  | 
| Douglas Gregor | 3c385e5 | 2009-02-14 18:57:46 +0000 | [diff] [blame] | 1020 |   // If this function is at translation-unit scope and we're not in | 
 | 1021 |   // C++, it refers to the C library function. | 
 | 1022 |   if (!Context.getLangOptions().CPlusPlus && | 
 | 1023 |       getDeclContext()->isTranslationUnit()) | 
 | 1024 |     return BuiltinID; | 
 | 1025 |  | 
 | 1026 |   // If the function is in an extern "C" linkage specification and is | 
 | 1027 |   // not marked "overloadable", it's the real function. | 
 | 1028 |   if (isa<LinkageSpecDecl>(getDeclContext()) && | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1029 |       cast<LinkageSpecDecl>(getDeclContext())->getLanguage() | 
| Douglas Gregor | 3c385e5 | 2009-02-14 18:57:46 +0000 | [diff] [blame] | 1030 |         == LinkageSpecDecl::lang_c && | 
| Argyrios Kyrtzidis | 40b598e | 2009-06-30 02:34:44 +0000 | [diff] [blame] | 1031 |       !getAttr<OverloadableAttr>()) | 
| Douglas Gregor | 3c385e5 | 2009-02-14 18:57:46 +0000 | [diff] [blame] | 1032 |     return BuiltinID; | 
 | 1033 |  | 
 | 1034 |   // Not a builtin | 
| Douglas Gregor | 3e41d60 | 2009-02-13 23:20:09 +0000 | [diff] [blame] | 1035 |   return 0; | 
 | 1036 | } | 
 | 1037 |  | 
 | 1038 |  | 
| Chris Lattner | 1ad9b28 | 2009-04-25 06:03:53 +0000 | [diff] [blame] | 1039 | /// getNumParams - Return the number of parameters this function must have | 
| Chris Lattner | 2dbd285 | 2009-04-25 06:12:16 +0000 | [diff] [blame] | 1040 | /// based on its FunctionType.  This is the length of the PararmInfo array | 
| Chris Lattner | 1ad9b28 | 2009-04-25 06:03:53 +0000 | [diff] [blame] | 1041 | /// after it has been created. | 
 | 1042 | unsigned FunctionDecl::getNumParams() const { | 
| John McCall | 183700f | 2009-09-21 23:43:11 +0000 | [diff] [blame] | 1043 |   const FunctionType *FT = getType()->getAs<FunctionType>(); | 
| Douglas Gregor | 72564e7 | 2009-02-26 23:50:07 +0000 | [diff] [blame] | 1044 |   if (isa<FunctionNoProtoType>(FT)) | 
| Chris Lattner | d3b9065 | 2008-03-15 05:43:15 +0000 | [diff] [blame] | 1045 |     return 0; | 
| Douglas Gregor | 72564e7 | 2009-02-26 23:50:07 +0000 | [diff] [blame] | 1046 |   return cast<FunctionProtoType>(FT)->getNumArgs(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1047 |  | 
| Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 1048 | } | 
 | 1049 |  | 
| Douglas Gregor | 838db38 | 2010-02-11 01:19:42 +0000 | [diff] [blame] | 1050 | void FunctionDecl::setParams(ParmVarDecl **NewParamInfo, unsigned NumParams) { | 
| Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 1051 |   assert(ParamInfo == 0 && "Already has param info!"); | 
| Chris Lattner | 2dbd285 | 2009-04-25 06:12:16 +0000 | [diff] [blame] | 1052 |   assert(NumParams == getNumParams() && "Parameter count mismatch!"); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1053 |  | 
| Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 1054 |   // Zero params -> null pointer. | 
 | 1055 |   if (NumParams) { | 
| Douglas Gregor | 838db38 | 2010-02-11 01:19:42 +0000 | [diff] [blame] | 1056 |     void *Mem = getASTContext().Allocate(sizeof(ParmVarDecl*)*NumParams); | 
| Ted Kremenek | fc76761 | 2009-01-14 00:42:25 +0000 | [diff] [blame] | 1057 |     ParamInfo = new (Mem) ParmVarDecl*[NumParams]; | 
| Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 1058 |     memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams); | 
| Argyrios Kyrtzidis | 55d608c | 2009-06-20 08:09:14 +0000 | [diff] [blame] | 1059 |  | 
| Argyrios Kyrtzidis | 96888cc | 2009-06-23 00:42:00 +0000 | [diff] [blame] | 1060 |     // Update source range. The check below allows us to set EndRangeLoc before | 
 | 1061 |     // setting the parameters. | 
| Argyrios Kyrtzidis | cb5f8f5 | 2009-06-23 00:42:15 +0000 | [diff] [blame] | 1062 |     if (EndRangeLoc.isInvalid() || EndRangeLoc == getLocation()) | 
| Argyrios Kyrtzidis | 55d608c | 2009-06-20 08:09:14 +0000 | [diff] [blame] | 1063 |       EndRangeLoc = NewParamInfo[NumParams-1]->getLocEnd(); | 
| Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 1064 |   } | 
 | 1065 | } | 
 | 1066 |  | 
| Chris Lattner | 8123a95 | 2008-04-10 02:22:51 +0000 | [diff] [blame] | 1067 | /// getMinRequiredArguments - Returns the minimum number of arguments | 
 | 1068 | /// needed to call this function. This may be fewer than the number of | 
 | 1069 | /// function parameters, if some of the parameters have default | 
| Chris Lattner | 9e97955 | 2008-04-12 23:52:44 +0000 | [diff] [blame] | 1070 | /// arguments (in C++). | 
| Chris Lattner | 8123a95 | 2008-04-10 02:22:51 +0000 | [diff] [blame] | 1071 | unsigned FunctionDecl::getMinRequiredArguments() const { | 
 | 1072 |   unsigned NumRequiredArgs = getNumParams(); | 
 | 1073 |   while (NumRequiredArgs > 0 | 
| Anders Carlsson | ae0b4e7 | 2009-06-06 04:14:07 +0000 | [diff] [blame] | 1074 |          && getParamDecl(NumRequiredArgs-1)->hasDefaultArg()) | 
| Chris Lattner | 8123a95 | 2008-04-10 02:22:51 +0000 | [diff] [blame] | 1075 |     --NumRequiredArgs; | 
 | 1076 |  | 
 | 1077 |   return NumRequiredArgs; | 
 | 1078 | } | 
 | 1079 |  | 
| Douglas Gregor | 7ced9c8 | 2009-10-27 21:11:48 +0000 | [diff] [blame] | 1080 | bool FunctionDecl::isInlined() const { | 
| Anders Carlsson | 48eda2c | 2009-12-04 22:35:50 +0000 | [diff] [blame] | 1081 |   // FIXME: This is not enough. Consider: | 
 | 1082 |   // | 
 | 1083 |   // inline void f(); | 
 | 1084 |   // void f() { } | 
 | 1085 |   // | 
 | 1086 |   // f is inlined, but does not have inline specified. | 
 | 1087 |   // To fix this we should add an 'inline' flag to FunctionDecl. | 
 | 1088 |   if (isInlineSpecified()) | 
| Douglas Gregor | 7d9c3c9 | 2009-10-27 23:26:40 +0000 | [diff] [blame] | 1089 |     return true; | 
| Anders Carlsson | 48eda2c | 2009-12-04 22:35:50 +0000 | [diff] [blame] | 1090 |    | 
 | 1091 |   if (isa<CXXMethodDecl>(this)) { | 
 | 1092 |     if (!isOutOfLine() || getCanonicalDecl()->isInlineSpecified()) | 
 | 1093 |       return true; | 
 | 1094 |   } | 
| Douglas Gregor | 7d9c3c9 | 2009-10-27 23:26:40 +0000 | [diff] [blame] | 1095 |  | 
 | 1096 |   switch (getTemplateSpecializationKind()) { | 
 | 1097 |   case TSK_Undeclared: | 
 | 1098 |   case TSK_ExplicitSpecialization: | 
 | 1099 |     return false; | 
 | 1100 |  | 
 | 1101 |   case TSK_ImplicitInstantiation: | 
 | 1102 |   case TSK_ExplicitInstantiationDeclaration: | 
 | 1103 |   case TSK_ExplicitInstantiationDefinition: | 
 | 1104 |     // Handle below. | 
 | 1105 |     break; | 
 | 1106 |   } | 
 | 1107 |  | 
 | 1108 |   const FunctionDecl *PatternDecl = getTemplateInstantiationPattern(); | 
 | 1109 |   Stmt *Pattern = 0; | 
 | 1110 |   if (PatternDecl) | 
 | 1111 |     Pattern = PatternDecl->getBody(PatternDecl); | 
 | 1112 |    | 
 | 1113 |   if (Pattern && PatternDecl) | 
 | 1114 |     return PatternDecl->isInlined(); | 
 | 1115 |    | 
 | 1116 |   return false; | 
| Douglas Gregor | 7ced9c8 | 2009-10-27 21:11:48 +0000 | [diff] [blame] | 1117 | } | 
 | 1118 |  | 
| Douglas Gregor | 7d9c3c9 | 2009-10-27 23:26:40 +0000 | [diff] [blame] | 1119 | /// \brief For an inline function definition in C or C++, determine whether the  | 
| Douglas Gregor | 1fc09a9 | 2009-09-13 07:46:26 +0000 | [diff] [blame] | 1120 | /// definition will be externally visible. | 
 | 1121 | /// | 
 | 1122 | /// Inline function definitions are always available for inlining optimizations. | 
 | 1123 | /// However, depending on the language dialect, declaration specifiers, and | 
 | 1124 | /// attributes, the definition of an inline function may or may not be | 
 | 1125 | /// "externally" visible to other translation units in the program. | 
 | 1126 | /// | 
 | 1127 | /// In C99, inline definitions are not externally visible by default. However, | 
| Mike Stump | 1e5fd7f | 2010-01-06 02:05:39 +0000 | [diff] [blame] | 1128 | /// if even one of the global-scope declarations is marked "extern inline", the | 
| Douglas Gregor | 1fc09a9 | 2009-09-13 07:46:26 +0000 | [diff] [blame] | 1129 | /// inline definition becomes externally visible (C99 6.7.4p6). | 
 | 1130 | /// | 
 | 1131 | /// In GNU89 mode, or if the gnu_inline attribute is attached to the function | 
 | 1132 | /// definition, we use the GNU semantics for inline, which are nearly the  | 
 | 1133 | /// opposite of C99 semantics. In particular, "inline" by itself will create  | 
 | 1134 | /// an externally visible symbol, but "extern inline" will not create an  | 
 | 1135 | /// externally visible symbol. | 
 | 1136 | bool FunctionDecl::isInlineDefinitionExternallyVisible() const { | 
 | 1137 |   assert(isThisDeclarationADefinition() && "Must have the function definition"); | 
| Douglas Gregor | 7ced9c8 | 2009-10-27 21:11:48 +0000 | [diff] [blame] | 1138 |   assert(isInlined() && "Function must be inline"); | 
| Douglas Gregor | 7d9c3c9 | 2009-10-27 23:26:40 +0000 | [diff] [blame] | 1139 |   ASTContext &Context = getASTContext(); | 
| Douglas Gregor | 1fc09a9 | 2009-09-13 07:46:26 +0000 | [diff] [blame] | 1140 |    | 
| Douglas Gregor | 7d9c3c9 | 2009-10-27 23:26:40 +0000 | [diff] [blame] | 1141 |   if (!Context.getLangOptions().C99 || hasAttr<GNUInlineAttr>()) { | 
| Douglas Gregor | 1fc09a9 | 2009-09-13 07:46:26 +0000 | [diff] [blame] | 1142 |     // GNU inline semantics. Based on a number of examples, we came up with the | 
 | 1143 |     // following heuristic: if the "inline" keyword is present on a | 
 | 1144 |     // declaration of the function but "extern" is not present on that | 
 | 1145 |     // declaration, then the symbol is externally visible. Otherwise, the GNU | 
 | 1146 |     // "extern inline" semantics applies and the symbol is not externally | 
 | 1147 |     // visible. | 
 | 1148 |     for (redecl_iterator Redecl = redecls_begin(), RedeclEnd = redecls_end(); | 
 | 1149 |          Redecl != RedeclEnd; | 
 | 1150 |          ++Redecl) { | 
| Douglas Gregor | 0130f3c | 2009-10-27 21:01:01 +0000 | [diff] [blame] | 1151 |       if (Redecl->isInlineSpecified() && Redecl->getStorageClass() != Extern) | 
| Douglas Gregor | 1fc09a9 | 2009-09-13 07:46:26 +0000 | [diff] [blame] | 1152 |         return true; | 
 | 1153 |     } | 
 | 1154 |      | 
 | 1155 |     // GNU "extern inline" semantics; no externally visible symbol. | 
| Douglas Gregor | 9f9bf25 | 2009-04-28 06:37:30 +0000 | [diff] [blame] | 1156 |     return false; | 
| Douglas Gregor | 1fc09a9 | 2009-09-13 07:46:26 +0000 | [diff] [blame] | 1157 |   } | 
 | 1158 |    | 
 | 1159 |   // C99 6.7.4p6: | 
 | 1160 |   //   [...] If all of the file scope declarations for a function in a  | 
 | 1161 |   //   translation unit include the inline function specifier without extern,  | 
 | 1162 |   //   then the definition in that translation unit is an inline definition. | 
 | 1163 |   for (redecl_iterator Redecl = redecls_begin(), RedeclEnd = redecls_end(); | 
 | 1164 |        Redecl != RedeclEnd; | 
 | 1165 |        ++Redecl) { | 
 | 1166 |     // Only consider file-scope declarations in this test. | 
 | 1167 |     if (!Redecl->getLexicalDeclContext()->isTranslationUnit()) | 
 | 1168 |       continue; | 
 | 1169 |      | 
| Douglas Gregor | 0130f3c | 2009-10-27 21:01:01 +0000 | [diff] [blame] | 1170 |     if (!Redecl->isInlineSpecified() || Redecl->getStorageClass() == Extern)  | 
| Douglas Gregor | 1fc09a9 | 2009-09-13 07:46:26 +0000 | [diff] [blame] | 1171 |       return true; // Not an inline definition | 
 | 1172 |   } | 
 | 1173 |    | 
 | 1174 |   // C99 6.7.4p6: | 
 | 1175 |   //   An inline definition does not provide an external definition for the  | 
 | 1176 |   //   function, and does not forbid an external definition in another  | 
 | 1177 |   //   translation unit. | 
| Douglas Gregor | 9f9bf25 | 2009-04-28 06:37:30 +0000 | [diff] [blame] | 1178 |   return false; | 
 | 1179 | } | 
 | 1180 |  | 
| Douglas Gregor | 1cd1b1e | 2008-11-06 22:13:31 +0000 | [diff] [blame] | 1181 | /// getOverloadedOperator - Which C++ overloaded operator this | 
 | 1182 | /// function represents, if any. | 
 | 1183 | OverloadedOperatorKind FunctionDecl::getOverloadedOperator() const { | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 1184 |   if (getDeclName().getNameKind() == DeclarationName::CXXOperatorName) | 
 | 1185 |     return getDeclName().getCXXOverloadedOperator(); | 
| Douglas Gregor | 1cd1b1e | 2008-11-06 22:13:31 +0000 | [diff] [blame] | 1186 |   else | 
 | 1187 |     return OO_None; | 
 | 1188 | } | 
 | 1189 |  | 
| Sean Hunt | a6c058d | 2010-01-13 09:01:02 +0000 | [diff] [blame] | 1190 | /// getLiteralIdentifier - The literal suffix identifier this function | 
 | 1191 | /// represents, if any. | 
 | 1192 | const IdentifierInfo *FunctionDecl::getLiteralIdentifier() const { | 
 | 1193 |   if (getDeclName().getNameKind() == DeclarationName::CXXLiteralOperatorName) | 
 | 1194 |     return getDeclName().getCXXLiteralIdentifier(); | 
 | 1195 |   else | 
 | 1196 |     return 0; | 
 | 1197 | } | 
 | 1198 |  | 
| Douglas Gregor | 2db3232 | 2009-10-07 23:56:10 +0000 | [diff] [blame] | 1199 | FunctionDecl *FunctionDecl::getInstantiatedFromMemberFunction() const { | 
| Douglas Gregor | b3ae4fc | 2009-10-12 20:18:28 +0000 | [diff] [blame] | 1200 |   if (MemberSpecializationInfo *Info = getMemberSpecializationInfo()) | 
| Douglas Gregor | 2db3232 | 2009-10-07 23:56:10 +0000 | [diff] [blame] | 1201 |     return cast<FunctionDecl>(Info->getInstantiatedFrom()); | 
 | 1202 |    | 
 | 1203 |   return 0; | 
 | 1204 | } | 
 | 1205 |  | 
| Douglas Gregor | b3ae4fc | 2009-10-12 20:18:28 +0000 | [diff] [blame] | 1206 | MemberSpecializationInfo *FunctionDecl::getMemberSpecializationInfo() const { | 
 | 1207 |   return TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>(); | 
 | 1208 | } | 
 | 1209 |  | 
| Douglas Gregor | 2db3232 | 2009-10-07 23:56:10 +0000 | [diff] [blame] | 1210 | void  | 
 | 1211 | FunctionDecl::setInstantiationOfMemberFunction(FunctionDecl *FD, | 
 | 1212 |                                                TemplateSpecializationKind TSK) { | 
 | 1213 |   assert(TemplateOrSpecialization.isNull() &&  | 
 | 1214 |          "Member function is already a specialization"); | 
 | 1215 |   MemberSpecializationInfo *Info  | 
 | 1216 |     = new (getASTContext()) MemberSpecializationInfo(FD, TSK); | 
 | 1217 |   TemplateOrSpecialization = Info; | 
 | 1218 | } | 
 | 1219 |  | 
| Douglas Gregor | 3b846b6 | 2009-10-27 20:53:28 +0000 | [diff] [blame] | 1220 | bool FunctionDecl::isImplicitlyInstantiable() const { | 
 | 1221 |   // If this function already has a definition or is invalid, it can't be | 
 | 1222 |   // implicitly instantiated. | 
 | 1223 |   if (isInvalidDecl() || getBody()) | 
 | 1224 |     return false; | 
 | 1225 |    | 
 | 1226 |   switch (getTemplateSpecializationKind()) { | 
 | 1227 |   case TSK_Undeclared: | 
 | 1228 |   case TSK_ExplicitSpecialization: | 
 | 1229 |   case TSK_ExplicitInstantiationDefinition: | 
 | 1230 |     return false; | 
 | 1231 |        | 
 | 1232 |   case TSK_ImplicitInstantiation: | 
 | 1233 |     return true; | 
 | 1234 |  | 
 | 1235 |   case TSK_ExplicitInstantiationDeclaration: | 
 | 1236 |     // Handled below. | 
 | 1237 |     break; | 
 | 1238 |   } | 
 | 1239 |  | 
 | 1240 |   // Find the actual template from which we will instantiate. | 
 | 1241 |   const FunctionDecl *PatternDecl = getTemplateInstantiationPattern(); | 
 | 1242 |   Stmt *Pattern = 0; | 
 | 1243 |   if (PatternDecl) | 
 | 1244 |     Pattern = PatternDecl->getBody(PatternDecl); | 
 | 1245 |    | 
 | 1246 |   // C++0x [temp.explicit]p9: | 
 | 1247 |   //   Except for inline functions, other explicit instantiation declarations | 
 | 1248 |   //   have the effect of suppressing the implicit instantiation of the entity | 
 | 1249 |   //   to which they refer.  | 
 | 1250 |   if (!Pattern || !PatternDecl) | 
 | 1251 |     return true; | 
 | 1252 |  | 
| Douglas Gregor | 7ced9c8 | 2009-10-27 21:11:48 +0000 | [diff] [blame] | 1253 |   return PatternDecl->isInlined(); | 
| Douglas Gregor | 3b846b6 | 2009-10-27 20:53:28 +0000 | [diff] [blame] | 1254 | }                       | 
 | 1255 |     | 
 | 1256 | FunctionDecl *FunctionDecl::getTemplateInstantiationPattern() const { | 
 | 1257 |   if (FunctionTemplateDecl *Primary = getPrimaryTemplate()) { | 
 | 1258 |     while (Primary->getInstantiatedFromMemberTemplate()) { | 
 | 1259 |       // If we have hit a point where the user provided a specialization of | 
 | 1260 |       // this template, we're done looking. | 
 | 1261 |       if (Primary->isMemberSpecialization()) | 
 | 1262 |         break; | 
 | 1263 |        | 
 | 1264 |       Primary = Primary->getInstantiatedFromMemberTemplate(); | 
 | 1265 |     } | 
 | 1266 |      | 
 | 1267 |     return Primary->getTemplatedDecl(); | 
 | 1268 |   }  | 
 | 1269 |      | 
 | 1270 |   return getInstantiatedFromMemberFunction(); | 
 | 1271 | } | 
 | 1272 |  | 
| Douglas Gregor | 16e8be2 | 2009-06-29 17:30:29 +0000 | [diff] [blame] | 1273 | FunctionTemplateDecl *FunctionDecl::getPrimaryTemplate() const { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1274 |   if (FunctionTemplateSpecializationInfo *Info | 
| Douglas Gregor | 16e8be2 | 2009-06-29 17:30:29 +0000 | [diff] [blame] | 1275 |         = TemplateOrSpecialization | 
 | 1276 |             .dyn_cast<FunctionTemplateSpecializationInfo*>()) { | 
| Douglas Gregor | 1fd2dd1 | 2009-06-29 22:39:32 +0000 | [diff] [blame] | 1277 |     return Info->Template.getPointer(); | 
| Douglas Gregor | 16e8be2 | 2009-06-29 17:30:29 +0000 | [diff] [blame] | 1278 |   } | 
 | 1279 |   return 0; | 
 | 1280 | } | 
 | 1281 |  | 
 | 1282 | const TemplateArgumentList * | 
 | 1283 | FunctionDecl::getTemplateSpecializationArgs() const { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1284 |   if (FunctionTemplateSpecializationInfo *Info | 
| Douglas Gregor | fd056bc | 2009-10-13 16:30:37 +0000 | [diff] [blame] | 1285 |         = TemplateOrSpecialization | 
 | 1286 |             .dyn_cast<FunctionTemplateSpecializationInfo*>()) { | 
| Douglas Gregor | 16e8be2 | 2009-06-29 17:30:29 +0000 | [diff] [blame] | 1287 |     return Info->TemplateArguments; | 
 | 1288 |   } | 
 | 1289 |   return 0; | 
 | 1290 | } | 
 | 1291 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1292 | void | 
| Douglas Gregor | 838db38 | 2010-02-11 01:19:42 +0000 | [diff] [blame] | 1293 | FunctionDecl::setFunctionTemplateSpecialization(FunctionTemplateDecl *Template, | 
| Douglas Gregor | 127102b | 2009-06-29 20:59:39 +0000 | [diff] [blame] | 1294 |                                      const TemplateArgumentList *TemplateArgs, | 
| Douglas Gregor | b9aa6b2 | 2009-09-24 23:14:47 +0000 | [diff] [blame] | 1295 |                                                 void *InsertPos, | 
 | 1296 |                                               TemplateSpecializationKind TSK) { | 
 | 1297 |   assert(TSK != TSK_Undeclared &&  | 
 | 1298 |          "Must specify the type of function template specialization"); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1299 |   FunctionTemplateSpecializationInfo *Info | 
| Douglas Gregor | 16e8be2 | 2009-06-29 17:30:29 +0000 | [diff] [blame] | 1300 |     = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>(); | 
| Douglas Gregor | 1637be7 | 2009-06-26 00:10:03 +0000 | [diff] [blame] | 1301 |   if (!Info) | 
| Douglas Gregor | 838db38 | 2010-02-11 01:19:42 +0000 | [diff] [blame] | 1302 |     Info = new (getASTContext()) FunctionTemplateSpecializationInfo; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1303 |  | 
| Douglas Gregor | 127102b | 2009-06-29 20:59:39 +0000 | [diff] [blame] | 1304 |   Info->Function = this; | 
| Douglas Gregor | 1fd2dd1 | 2009-06-29 22:39:32 +0000 | [diff] [blame] | 1305 |   Info->Template.setPointer(Template); | 
| Douglas Gregor | b9aa6b2 | 2009-09-24 23:14:47 +0000 | [diff] [blame] | 1306 |   Info->Template.setInt(TSK - 1); | 
| Douglas Gregor | 1637be7 | 2009-06-26 00:10:03 +0000 | [diff] [blame] | 1307 |   Info->TemplateArguments = TemplateArgs; | 
 | 1308 |   TemplateOrSpecialization = Info; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1309 |  | 
| Douglas Gregor | 127102b | 2009-06-29 20:59:39 +0000 | [diff] [blame] | 1310 |   // Insert this function template specialization into the set of known | 
| Douglas Gregor | b9aa6b2 | 2009-09-24 23:14:47 +0000 | [diff] [blame] | 1311 |   // function template specializations. | 
 | 1312 |   if (InsertPos) | 
 | 1313 |     Template->getSpecializations().InsertNode(Info, InsertPos); | 
 | 1314 |   else { | 
 | 1315 |     // Try to insert the new node. If there is an existing node, remove it  | 
 | 1316 |     // first. | 
 | 1317 |     FunctionTemplateSpecializationInfo *Existing | 
 | 1318 |       = Template->getSpecializations().GetOrInsertNode(Info); | 
 | 1319 |     if (Existing) { | 
 | 1320 |       Template->getSpecializations().RemoveNode(Existing); | 
 | 1321 |       Template->getSpecializations().GetOrInsertNode(Info); | 
 | 1322 |     } | 
 | 1323 |   } | 
| Douglas Gregor | 1637be7 | 2009-06-26 00:10:03 +0000 | [diff] [blame] | 1324 | } | 
 | 1325 |  | 
| John McCall | af2094e | 2010-04-08 09:05:18 +0000 | [diff] [blame] | 1326 | void | 
 | 1327 | FunctionDecl::setDependentTemplateSpecialization(ASTContext &Context, | 
 | 1328 |                                     const UnresolvedSetImpl &Templates, | 
 | 1329 |                              const TemplateArgumentListInfo &TemplateArgs) { | 
 | 1330 |   assert(TemplateOrSpecialization.isNull()); | 
 | 1331 |   size_t Size = sizeof(DependentFunctionTemplateSpecializationInfo); | 
 | 1332 |   Size += Templates.size() * sizeof(FunctionTemplateDecl*); | 
| John McCall | 21c0160 | 2010-04-13 22:18:28 +0000 | [diff] [blame] | 1333 |   Size += TemplateArgs.size() * sizeof(TemplateArgumentLoc); | 
| John McCall | af2094e | 2010-04-08 09:05:18 +0000 | [diff] [blame] | 1334 |   void *Buffer = Context.Allocate(Size); | 
 | 1335 |   DependentFunctionTemplateSpecializationInfo *Info = | 
 | 1336 |     new (Buffer) DependentFunctionTemplateSpecializationInfo(Templates, | 
 | 1337 |                                                              TemplateArgs); | 
 | 1338 |   TemplateOrSpecialization = Info; | 
 | 1339 | } | 
 | 1340 |  | 
 | 1341 | DependentFunctionTemplateSpecializationInfo:: | 
 | 1342 | DependentFunctionTemplateSpecializationInfo(const UnresolvedSetImpl &Ts, | 
 | 1343 |                                       const TemplateArgumentListInfo &TArgs) | 
 | 1344 |   : AngleLocs(TArgs.getLAngleLoc(), TArgs.getRAngleLoc()) { | 
 | 1345 |  | 
 | 1346 |   d.NumTemplates = Ts.size(); | 
 | 1347 |   d.NumArgs = TArgs.size(); | 
 | 1348 |  | 
 | 1349 |   FunctionTemplateDecl **TsArray = | 
 | 1350 |     const_cast<FunctionTemplateDecl**>(getTemplates()); | 
 | 1351 |   for (unsigned I = 0, E = Ts.size(); I != E; ++I) | 
 | 1352 |     TsArray[I] = cast<FunctionTemplateDecl>(Ts[I]->getUnderlyingDecl()); | 
 | 1353 |  | 
 | 1354 |   TemplateArgumentLoc *ArgsArray = | 
 | 1355 |     const_cast<TemplateArgumentLoc*>(getTemplateArgs()); | 
 | 1356 |   for (unsigned I = 0, E = TArgs.size(); I != E; ++I) | 
 | 1357 |     new (&ArgsArray[I]) TemplateArgumentLoc(TArgs[I]); | 
 | 1358 | } | 
 | 1359 |  | 
| Douglas Gregor | d0e3daf | 2009-09-04 22:48:11 +0000 | [diff] [blame] | 1360 | TemplateSpecializationKind FunctionDecl::getTemplateSpecializationKind() const { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1361 |   // For a function template specialization, query the specialization | 
| Douglas Gregor | d0e3daf | 2009-09-04 22:48:11 +0000 | [diff] [blame] | 1362 |   // information object. | 
| Douglas Gregor | 2db3232 | 2009-10-07 23:56:10 +0000 | [diff] [blame] | 1363 |   FunctionTemplateSpecializationInfo *FTSInfo | 
| Douglas Gregor | 1fd2dd1 | 2009-06-29 22:39:32 +0000 | [diff] [blame] | 1364 |     = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>(); | 
| Douglas Gregor | 2db3232 | 2009-10-07 23:56:10 +0000 | [diff] [blame] | 1365 |   if (FTSInfo) | 
 | 1366 |     return FTSInfo->getTemplateSpecializationKind(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1367 |  | 
| Douglas Gregor | 2db3232 | 2009-10-07 23:56:10 +0000 | [diff] [blame] | 1368 |   MemberSpecializationInfo *MSInfo | 
 | 1369 |     = TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>(); | 
 | 1370 |   if (MSInfo) | 
 | 1371 |     return MSInfo->getTemplateSpecializationKind(); | 
 | 1372 |    | 
 | 1373 |   return TSK_Undeclared; | 
| Douglas Gregor | d0e3daf | 2009-09-04 22:48:11 +0000 | [diff] [blame] | 1374 | } | 
 | 1375 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1376 | void | 
| Douglas Gregor | 0a897e3 | 2009-10-15 17:21:20 +0000 | [diff] [blame] | 1377 | FunctionDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK, | 
 | 1378 |                                           SourceLocation PointOfInstantiation) { | 
 | 1379 |   if (FunctionTemplateSpecializationInfo *FTSInfo | 
 | 1380 |         = TemplateOrSpecialization.dyn_cast< | 
 | 1381 |                                     FunctionTemplateSpecializationInfo*>()) { | 
 | 1382 |     FTSInfo->setTemplateSpecializationKind(TSK); | 
 | 1383 |     if (TSK != TSK_ExplicitSpecialization && | 
 | 1384 |         PointOfInstantiation.isValid() && | 
 | 1385 |         FTSInfo->getPointOfInstantiation().isInvalid()) | 
 | 1386 |       FTSInfo->setPointOfInstantiation(PointOfInstantiation); | 
 | 1387 |   } else if (MemberSpecializationInfo *MSInfo | 
 | 1388 |              = TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>()) { | 
 | 1389 |     MSInfo->setTemplateSpecializationKind(TSK); | 
 | 1390 |     if (TSK != TSK_ExplicitSpecialization && | 
 | 1391 |         PointOfInstantiation.isValid() && | 
 | 1392 |         MSInfo->getPointOfInstantiation().isInvalid()) | 
 | 1393 |       MSInfo->setPointOfInstantiation(PointOfInstantiation); | 
 | 1394 |   } else | 
 | 1395 |     assert(false && "Function cannot have a template specialization kind"); | 
 | 1396 | } | 
 | 1397 |  | 
 | 1398 | SourceLocation FunctionDecl::getPointOfInstantiation() const { | 
| Douglas Gregor | 2db3232 | 2009-10-07 23:56:10 +0000 | [diff] [blame] | 1399 |   if (FunctionTemplateSpecializationInfo *FTSInfo | 
 | 1400 |         = TemplateOrSpecialization.dyn_cast< | 
 | 1401 |                                         FunctionTemplateSpecializationInfo*>()) | 
| Douglas Gregor | 0a897e3 | 2009-10-15 17:21:20 +0000 | [diff] [blame] | 1402 |     return FTSInfo->getPointOfInstantiation(); | 
| Douglas Gregor | 2db3232 | 2009-10-07 23:56:10 +0000 | [diff] [blame] | 1403 |   else if (MemberSpecializationInfo *MSInfo | 
 | 1404 |              = TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>()) | 
| Douglas Gregor | 0a897e3 | 2009-10-15 17:21:20 +0000 | [diff] [blame] | 1405 |     return MSInfo->getPointOfInstantiation(); | 
 | 1406 |    | 
 | 1407 |   return SourceLocation(); | 
| Douglas Gregor | 1fd2dd1 | 2009-06-29 22:39:32 +0000 | [diff] [blame] | 1408 | } | 
 | 1409 |  | 
| Douglas Gregor | 9f18507 | 2009-09-11 20:15:17 +0000 | [diff] [blame] | 1410 | bool FunctionDecl::isOutOfLine() const { | 
| Douglas Gregor | 9f18507 | 2009-09-11 20:15:17 +0000 | [diff] [blame] | 1411 |   if (Decl::isOutOfLine()) | 
 | 1412 |     return true; | 
 | 1413 |    | 
 | 1414 |   // If this function was instantiated from a member function of a  | 
 | 1415 |   // class template, check whether that member function was defined out-of-line. | 
 | 1416 |   if (FunctionDecl *FD = getInstantiatedFromMemberFunction()) { | 
 | 1417 |     const FunctionDecl *Definition; | 
 | 1418 |     if (FD->getBody(Definition)) | 
 | 1419 |       return Definition->isOutOfLine(); | 
 | 1420 |   } | 
 | 1421 |    | 
 | 1422 |   // If this function was instantiated from a function template, | 
 | 1423 |   // check whether that function template was defined out-of-line. | 
 | 1424 |   if (FunctionTemplateDecl *FunTmpl = getPrimaryTemplate()) { | 
 | 1425 |     const FunctionDecl *Definition; | 
 | 1426 |     if (FunTmpl->getTemplatedDecl()->getBody(Definition)) | 
 | 1427 |       return Definition->isOutOfLine(); | 
 | 1428 |   } | 
 | 1429 |    | 
 | 1430 |   return false; | 
 | 1431 | } | 
 | 1432 |  | 
| Chris Lattner | 8a93423 | 2008-03-31 00:36:02 +0000 | [diff] [blame] | 1433 | //===----------------------------------------------------------------------===// | 
| Sebastian Redl | 7783bfc | 2010-01-26 22:01:41 +0000 | [diff] [blame] | 1434 | // FieldDecl Implementation | 
 | 1435 | //===----------------------------------------------------------------------===// | 
 | 1436 |  | 
 | 1437 | FieldDecl *FieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, | 
 | 1438 |                              IdentifierInfo *Id, QualType T, | 
 | 1439 |                              TypeSourceInfo *TInfo, Expr *BW, bool Mutable) { | 
 | 1440 |   return new (C) FieldDecl(Decl::Field, DC, L, Id, T, TInfo, BW, Mutable); | 
 | 1441 | } | 
 | 1442 |  | 
 | 1443 | bool FieldDecl::isAnonymousStructOrUnion() const { | 
 | 1444 |   if (!isImplicit() || getDeclName()) | 
 | 1445 |     return false; | 
 | 1446 |  | 
 | 1447 |   if (const RecordType *Record = getType()->getAs<RecordType>()) | 
 | 1448 |     return Record->getDecl()->isAnonymousStructOrUnion(); | 
 | 1449 |  | 
 | 1450 |   return false; | 
 | 1451 | } | 
 | 1452 |  | 
 | 1453 | //===----------------------------------------------------------------------===// | 
| Douglas Gregor | bcbffc4 | 2009-01-07 00:43:41 +0000 | [diff] [blame] | 1454 | // TagDecl Implementation | 
| Ted Kremenek | 4b7c983 | 2008-09-05 17:16:31 +0000 | [diff] [blame] | 1455 | //===----------------------------------------------------------------------===// | 
 | 1456 |  | 
| John McCall | b621766 | 2010-03-15 10:12:16 +0000 | [diff] [blame] | 1457 | void TagDecl::Destroy(ASTContext &C) { | 
 | 1458 |   if (hasExtInfo()) | 
 | 1459 |     C.Deallocate(getExtInfo()); | 
 | 1460 |   TypeDecl::Destroy(C); | 
 | 1461 | } | 
 | 1462 |  | 
| Argyrios Kyrtzidis | f602c8b | 2009-07-14 03:17:17 +0000 | [diff] [blame] | 1463 | SourceRange TagDecl::getSourceRange() const { | 
 | 1464 |   SourceLocation E = RBraceLoc.isValid() ? RBraceLoc : getLocation(); | 
| Douglas Gregor | 741dd9a | 2009-07-21 14:46:17 +0000 | [diff] [blame] | 1465 |   return SourceRange(TagKeywordLoc, E); | 
| Argyrios Kyrtzidis | f602c8b | 2009-07-14 03:17:17 +0000 | [diff] [blame] | 1466 | } | 
 | 1467 |  | 
| Argyrios Kyrtzidis | b57a4fe | 2009-07-18 00:34:07 +0000 | [diff] [blame] | 1468 | TagDecl* TagDecl::getCanonicalDecl() { | 
| Douglas Gregor | 8e9e9ef | 2009-07-29 23:36:44 +0000 | [diff] [blame] | 1469 |   return getFirstDeclaration(); | 
| Argyrios Kyrtzidis | b57a4fe | 2009-07-18 00:34:07 +0000 | [diff] [blame] | 1470 | } | 
 | 1471 |  | 
| Douglas Gregor | 0b7a158 | 2009-01-17 00:42:38 +0000 | [diff] [blame] | 1472 | void TagDecl::startDefinition() { | 
| Douglas Gregor | 8e9e9ef | 2009-07-29 23:36:44 +0000 | [diff] [blame] | 1473 |   if (TagType *TagT = const_cast<TagType *>(TypeForDecl->getAs<TagType>())) { | 
 | 1474 |     TagT->decl.setPointer(this); | 
 | 1475 |     TagT->decl.setInt(1); | 
 | 1476 |   } | 
| John McCall | 86ff308 | 2010-02-04 22:26:26 +0000 | [diff] [blame] | 1477 |  | 
 | 1478 |   if (isa<CXXRecordDecl>(this)) { | 
 | 1479 |     CXXRecordDecl *D = cast<CXXRecordDecl>(this); | 
 | 1480 |     struct CXXRecordDecl::DefinitionData *Data =  | 
 | 1481 |       new (getASTContext()) struct CXXRecordDecl::DefinitionData(D); | 
| John McCall | 2243288 | 2010-03-26 21:56:38 +0000 | [diff] [blame] | 1482 |     for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) | 
 | 1483 |       cast<CXXRecordDecl>(*I)->DefinitionData = Data; | 
| John McCall | 86ff308 | 2010-02-04 22:26:26 +0000 | [diff] [blame] | 1484 |   } | 
| Douglas Gregor | 0b7a158 | 2009-01-17 00:42:38 +0000 | [diff] [blame] | 1485 | } | 
 | 1486 |  | 
 | 1487 | void TagDecl::completeDefinition() { | 
| John McCall | 5cfa011 | 2010-02-05 01:33:36 +0000 | [diff] [blame] | 1488 |   assert((!isa<CXXRecordDecl>(this) || | 
 | 1489 |           cast<CXXRecordDecl>(this)->hasDefinition()) && | 
 | 1490 |          "definition completed but not started"); | 
 | 1491 |  | 
| Douglas Gregor | 0b7a158 | 2009-01-17 00:42:38 +0000 | [diff] [blame] | 1492 |   IsDefinition = true; | 
| Douglas Gregor | 8e9e9ef | 2009-07-29 23:36:44 +0000 | [diff] [blame] | 1493 |   if (TagType *TagT = const_cast<TagType *>(TypeForDecl->getAs<TagType>())) { | 
 | 1494 |     assert(TagT->decl.getPointer() == this && | 
 | 1495 |            "Attempt to redefine a tag definition?"); | 
 | 1496 |     TagT->decl.setInt(0); | 
 | 1497 |   } | 
| Douglas Gregor | 0b7a158 | 2009-01-17 00:42:38 +0000 | [diff] [blame] | 1498 | } | 
 | 1499 |  | 
| Douglas Gregor | 952b017 | 2010-02-11 01:04:33 +0000 | [diff] [blame] | 1500 | TagDecl* TagDecl::getDefinition() const { | 
| Douglas Gregor | 8e9e9ef | 2009-07-29 23:36:44 +0000 | [diff] [blame] | 1501 |   if (isDefinition()) | 
 | 1502 |     return const_cast<TagDecl *>(this); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1503 |  | 
 | 1504 |   for (redecl_iterator R = redecls_begin(), REnd = redecls_end(); | 
| Douglas Gregor | 8e9e9ef | 2009-07-29 23:36:44 +0000 | [diff] [blame] | 1505 |        R != REnd; ++R) | 
 | 1506 |     if (R->isDefinition()) | 
 | 1507 |       return *R; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1508 |  | 
| Douglas Gregor | 8e9e9ef | 2009-07-29 23:36:44 +0000 | [diff] [blame] | 1509 |   return 0; | 
| Ted Kremenek | 4b7c983 | 2008-09-05 17:16:31 +0000 | [diff] [blame] | 1510 | } | 
 | 1511 |  | 
| John McCall | f1bbbb4 | 2009-09-04 01:14:41 +0000 | [diff] [blame] | 1512 | TagDecl::TagKind TagDecl::getTagKindForTypeSpec(unsigned TypeSpec) { | 
 | 1513 |   switch (TypeSpec) { | 
| Jeffrey Yasskin | 9f61aa9 | 2009-12-12 05:05:38 +0000 | [diff] [blame] | 1514 |   default: llvm_unreachable("unexpected type specifier"); | 
| John McCall | f1bbbb4 | 2009-09-04 01:14:41 +0000 | [diff] [blame] | 1515 |   case DeclSpec::TST_struct: return TK_struct; | 
 | 1516 |   case DeclSpec::TST_class: return TK_class; | 
 | 1517 |   case DeclSpec::TST_union: return TK_union; | 
 | 1518 |   case DeclSpec::TST_enum: return TK_enum; | 
 | 1519 |   } | 
 | 1520 | } | 
 | 1521 |  | 
| John McCall | b621766 | 2010-03-15 10:12:16 +0000 | [diff] [blame] | 1522 | void TagDecl::setQualifierInfo(NestedNameSpecifier *Qualifier, | 
 | 1523 |                                SourceRange QualifierRange) { | 
 | 1524 |   if (Qualifier) { | 
 | 1525 |     // Make sure the extended qualifier info is allocated. | 
 | 1526 |     if (!hasExtInfo()) | 
 | 1527 |       TypedefDeclOrQualifier = new (getASTContext()) ExtInfo; | 
 | 1528 |     // Set qualifier info. | 
 | 1529 |     getExtInfo()->NNS = Qualifier; | 
 | 1530 |     getExtInfo()->NNSRange = QualifierRange; | 
 | 1531 |   } | 
 | 1532 |   else { | 
 | 1533 |     // Here Qualifier == 0, i.e., we are removing the qualifier (if any). | 
 | 1534 |     assert(QualifierRange.isInvalid()); | 
 | 1535 |     if (hasExtInfo()) { | 
 | 1536 |       getASTContext().Deallocate(getExtInfo()); | 
 | 1537 |       TypedefDeclOrQualifier = (TypedefDecl*) 0; | 
 | 1538 |     } | 
 | 1539 |   } | 
 | 1540 | } | 
 | 1541 |  | 
| Ted Kremenek | 4b7c983 | 2008-09-05 17:16:31 +0000 | [diff] [blame] | 1542 | //===----------------------------------------------------------------------===// | 
| Sebastian Redl | 7783bfc | 2010-01-26 22:01:41 +0000 | [diff] [blame] | 1543 | // EnumDecl Implementation | 
 | 1544 | //===----------------------------------------------------------------------===// | 
 | 1545 |  | 
 | 1546 | EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, | 
 | 1547 |                            IdentifierInfo *Id, SourceLocation TKL, | 
 | 1548 |                            EnumDecl *PrevDecl) { | 
 | 1549 |   EnumDecl *Enum = new (C) EnumDecl(DC, L, Id, PrevDecl, TKL); | 
 | 1550 |   C.getTypeDeclType(Enum, PrevDecl); | 
 | 1551 |   return Enum; | 
 | 1552 | } | 
 | 1553 |  | 
 | 1554 | void EnumDecl::Destroy(ASTContext& C) { | 
| John McCall | b621766 | 2010-03-15 10:12:16 +0000 | [diff] [blame] | 1555 |   TagDecl::Destroy(C); | 
| Sebastian Redl | 7783bfc | 2010-01-26 22:01:41 +0000 | [diff] [blame] | 1556 | } | 
 | 1557 |  | 
| Douglas Gregor | 838db38 | 2010-02-11 01:19:42 +0000 | [diff] [blame] | 1558 | void EnumDecl::completeDefinition(QualType NewType, | 
| Sebastian Redl | 7783bfc | 2010-01-26 22:01:41 +0000 | [diff] [blame] | 1559 |                                   QualType NewPromotionType) { | 
 | 1560 |   assert(!isDefinition() && "Cannot redefine enums!"); | 
 | 1561 |   IntegerType = NewType; | 
 | 1562 |   PromotionType = NewPromotionType; | 
 | 1563 |   TagDecl::completeDefinition(); | 
 | 1564 | } | 
 | 1565 |  | 
 | 1566 | //===----------------------------------------------------------------------===// | 
| Chris Lattner | 8a93423 | 2008-03-31 00:36:02 +0000 | [diff] [blame] | 1567 | // RecordDecl Implementation | 
 | 1568 | //===----------------------------------------------------------------------===// | 
| Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 1569 |  | 
| Argyrios Kyrtzidis | 35bc082 | 2008-10-15 00:42:39 +0000 | [diff] [blame] | 1570 | RecordDecl::RecordDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L, | 
| Douglas Gregor | 8e9e9ef | 2009-07-29 23:36:44 +0000 | [diff] [blame] | 1571 |                        IdentifierInfo *Id, RecordDecl *PrevDecl, | 
 | 1572 |                        SourceLocation TKL) | 
 | 1573 |   : TagDecl(DK, TK, DC, L, Id, PrevDecl, TKL) { | 
| Ted Kremenek | 6359792 | 2008-09-02 21:12:32 +0000 | [diff] [blame] | 1574 |   HasFlexibleArrayMember = false; | 
| Douglas Gregor | bcbffc4 | 2009-01-07 00:43:41 +0000 | [diff] [blame] | 1575 |   AnonymousStructOrUnion = false; | 
| Fariborz Jahanian | 082b02e | 2009-07-08 01:18:33 +0000 | [diff] [blame] | 1576 |   HasObjectMember = false; | 
| Ted Kremenek | 6359792 | 2008-09-02 21:12:32 +0000 | [diff] [blame] | 1577 |   assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!"); | 
| Ted Kremenek | 6359792 | 2008-09-02 21:12:32 +0000 | [diff] [blame] | 1578 | } | 
 | 1579 |  | 
 | 1580 | RecordDecl *RecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC, | 
| Ted Kremenek | 4b7c983 | 2008-09-05 17:16:31 +0000 | [diff] [blame] | 1581 |                                SourceLocation L, IdentifierInfo *Id, | 
| Douglas Gregor | 741dd9a | 2009-07-21 14:46:17 +0000 | [diff] [blame] | 1582 |                                SourceLocation TKL, RecordDecl* PrevDecl) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1583 |  | 
| Douglas Gregor | 8e9e9ef | 2009-07-29 23:36:44 +0000 | [diff] [blame] | 1584 |   RecordDecl* R = new (C) RecordDecl(Record, TK, DC, L, Id, PrevDecl, TKL); | 
| Ted Kremenek | 4b7c983 | 2008-09-05 17:16:31 +0000 | [diff] [blame] | 1585 |   C.getTypeDeclType(R, PrevDecl); | 
 | 1586 |   return R; | 
| Ted Kremenek | 6359792 | 2008-09-02 21:12:32 +0000 | [diff] [blame] | 1587 | } | 
 | 1588 |  | 
| Argyrios Kyrtzidis | 997b6c6 | 2008-08-08 14:08:55 +0000 | [diff] [blame] | 1589 | RecordDecl::~RecordDecl() { | 
| Argyrios Kyrtzidis | 997b6c6 | 2008-08-08 14:08:55 +0000 | [diff] [blame] | 1590 | } | 
 | 1591 |  | 
 | 1592 | void RecordDecl::Destroy(ASTContext& C) { | 
| Argyrios Kyrtzidis | 997b6c6 | 2008-08-08 14:08:55 +0000 | [diff] [blame] | 1593 |   TagDecl::Destroy(C); | 
 | 1594 | } | 
 | 1595 |  | 
| Douglas Gregor | c9b5b40 | 2009-03-25 15:59:44 +0000 | [diff] [blame] | 1596 | bool RecordDecl::isInjectedClassName() const { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1597 |   return isImplicit() && getDeclName() && getDeclContext()->isRecord() && | 
| Douglas Gregor | c9b5b40 | 2009-03-25 15:59:44 +0000 | [diff] [blame] | 1598 |     cast<RecordDecl>(getDeclContext())->getDeclName() == getDeclName(); | 
 | 1599 | } | 
 | 1600 |  | 
| Douglas Gregor | 44b4321 | 2008-12-11 16:49:14 +0000 | [diff] [blame] | 1601 | /// completeDefinition - Notes that the definition of this type is now | 
 | 1602 | /// complete. | 
| Douglas Gregor | 838db38 | 2010-02-11 01:19:42 +0000 | [diff] [blame] | 1603 | void RecordDecl::completeDefinition() { | 
| Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 1604 |   assert(!isDefinition() && "Cannot redefine record!"); | 
| Douglas Gregor | 0b7a158 | 2009-01-17 00:42:38 +0000 | [diff] [blame] | 1605 |   TagDecl::completeDefinition(); | 
| Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 1606 | } | 
 | 1607 |  | 
| Steve Naroff | 56ee689 | 2008-10-08 17:01:13 +0000 | [diff] [blame] | 1608 | //===----------------------------------------------------------------------===// | 
 | 1609 | // BlockDecl Implementation | 
 | 1610 | //===----------------------------------------------------------------------===// | 
 | 1611 |  | 
 | 1612 | BlockDecl::~BlockDecl() { | 
 | 1613 | } | 
 | 1614 |  | 
 | 1615 | void BlockDecl::Destroy(ASTContext& C) { | 
 | 1616 |   if (Body) | 
 | 1617 |     Body->Destroy(C); | 
 | 1618 |  | 
 | 1619 |   for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I) | 
 | 1620 |     (*I)->Destroy(C); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1621 |  | 
 | 1622 |   C.Deallocate(ParamInfo); | 
| Steve Naroff | 56ee689 | 2008-10-08 17:01:13 +0000 | [diff] [blame] | 1623 |   Decl::Destroy(C); | 
 | 1624 | } | 
| Steve Naroff | e78b809 | 2009-03-13 16:56:44 +0000 | [diff] [blame] | 1625 |  | 
| Douglas Gregor | 838db38 | 2010-02-11 01:19:42 +0000 | [diff] [blame] | 1626 | void BlockDecl::setParams(ParmVarDecl **NewParamInfo, | 
| Steve Naroff | e78b809 | 2009-03-13 16:56:44 +0000 | [diff] [blame] | 1627 |                           unsigned NParms) { | 
 | 1628 |   assert(ParamInfo == 0 && "Already has param info!"); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1629 |  | 
| Steve Naroff | e78b809 | 2009-03-13 16:56:44 +0000 | [diff] [blame] | 1630 |   // Zero params -> null pointer. | 
 | 1631 |   if (NParms) { | 
 | 1632 |     NumParams = NParms; | 
| Douglas Gregor | 838db38 | 2010-02-11 01:19:42 +0000 | [diff] [blame] | 1633 |     void *Mem = getASTContext().Allocate(sizeof(ParmVarDecl*)*NumParams); | 
| Steve Naroff | e78b809 | 2009-03-13 16:56:44 +0000 | [diff] [blame] | 1634 |     ParamInfo = new (Mem) ParmVarDecl*[NumParams]; | 
 | 1635 |     memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams); | 
 | 1636 |   } | 
 | 1637 | } | 
 | 1638 |  | 
 | 1639 | unsigned BlockDecl::getNumParams() const { | 
 | 1640 |   return NumParams; | 
 | 1641 | } | 
| Sebastian Redl | 7783bfc | 2010-01-26 22:01:41 +0000 | [diff] [blame] | 1642 |  | 
 | 1643 |  | 
 | 1644 | //===----------------------------------------------------------------------===// | 
 | 1645 | // Other Decl Allocation/Deallocation Method Implementations | 
 | 1646 | //===----------------------------------------------------------------------===// | 
 | 1647 |  | 
 | 1648 | TranslationUnitDecl *TranslationUnitDecl::Create(ASTContext &C) { | 
 | 1649 |   return new (C) TranslationUnitDecl(C); | 
 | 1650 | } | 
 | 1651 |  | 
 | 1652 | NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC, | 
 | 1653 |                                      SourceLocation L, IdentifierInfo *Id) { | 
 | 1654 |   return new (C) NamespaceDecl(DC, L, Id); | 
 | 1655 | } | 
 | 1656 |  | 
 | 1657 | void NamespaceDecl::Destroy(ASTContext& C) { | 
 | 1658 |   // NamespaceDecl uses "NextDeclarator" to chain namespace declarations | 
 | 1659 |   // together. They are all top-level Decls. | 
 | 1660 |  | 
 | 1661 |   this->~NamespaceDecl(); | 
| John McCall | b621766 | 2010-03-15 10:12:16 +0000 | [diff] [blame] | 1662 |   Decl::Destroy(C); | 
| Sebastian Redl | 7783bfc | 2010-01-26 22:01:41 +0000 | [diff] [blame] | 1663 | } | 
 | 1664 |  | 
 | 1665 |  | 
 | 1666 | ImplicitParamDecl *ImplicitParamDecl::Create(ASTContext &C, DeclContext *DC, | 
 | 1667 |     SourceLocation L, IdentifierInfo *Id, QualType T) { | 
 | 1668 |   return new (C) ImplicitParamDecl(ImplicitParam, DC, L, Id, T); | 
 | 1669 | } | 
 | 1670 |  | 
 | 1671 | FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC, | 
 | 1672 |                                    SourceLocation L, | 
 | 1673 |                                    DeclarationName N, QualType T, | 
 | 1674 |                                    TypeSourceInfo *TInfo, | 
| Douglas Gregor | 16573fa | 2010-04-19 22:54:31 +0000 | [diff] [blame] | 1675 |                                    StorageClass S, StorageClass SCAsWritten, | 
 | 1676 |                                    bool isInline, bool hasWrittenPrototype) { | 
 | 1677 |   FunctionDecl *New = new (C) FunctionDecl(Function, DC, L, N, T, TInfo, | 
 | 1678 |                                            S, SCAsWritten, isInline); | 
| Sebastian Redl | 7783bfc | 2010-01-26 22:01:41 +0000 | [diff] [blame] | 1679 |   New->HasWrittenPrototype = hasWrittenPrototype; | 
 | 1680 |   return New; | 
 | 1681 | } | 
 | 1682 |  | 
 | 1683 | BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) { | 
 | 1684 |   return new (C) BlockDecl(DC, L); | 
 | 1685 | } | 
 | 1686 |  | 
 | 1687 | EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD, | 
 | 1688 |                                            SourceLocation L, | 
 | 1689 |                                            IdentifierInfo *Id, QualType T, | 
 | 1690 |                                            Expr *E, const llvm::APSInt &V) { | 
 | 1691 |   return new (C) EnumConstantDecl(CD, L, Id, T, E, V); | 
 | 1692 | } | 
 | 1693 |  | 
 | 1694 | void EnumConstantDecl::Destroy(ASTContext& C) { | 
 | 1695 |   if (Init) Init->Destroy(C); | 
| John McCall | b621766 | 2010-03-15 10:12:16 +0000 | [diff] [blame] | 1696 |   ValueDecl::Destroy(C); | 
| Sebastian Redl | 7783bfc | 2010-01-26 22:01:41 +0000 | [diff] [blame] | 1697 | } | 
 | 1698 |  | 
 | 1699 | TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC, | 
 | 1700 |                                  SourceLocation L, IdentifierInfo *Id, | 
 | 1701 |                                  TypeSourceInfo *TInfo) { | 
 | 1702 |   return new (C) TypedefDecl(DC, L, Id, TInfo); | 
 | 1703 | } | 
 | 1704 |  | 
 | 1705 | // Anchor TypedefDecl's vtable here. | 
 | 1706 | TypedefDecl::~TypedefDecl() {} | 
 | 1707 |  | 
 | 1708 | FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, DeclContext *DC, | 
 | 1709 |                                            SourceLocation L, | 
 | 1710 |                                            StringLiteral *Str) { | 
 | 1711 |   return new (C) FileScopeAsmDecl(DC, L, Str); | 
 | 1712 | } |