Sema.cpp revision 9299f3fa85796613cc787a2062c9562d07c8613e
1abea951c34876a5374d0e3678c7989b225c5c895Anders Carlsson//===--- Sema.cpp - AST Builder and Semantic Analysis Implementation ------===// 2c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall// 3c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall// The LLVM Compiler Infrastructure 4c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall// 5c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall// This file is distributed under the University of Illinois Open Source 6c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall// License. See LICENSE.TXT for details. 7c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall// 8c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall//===----------------------------------------------------------------------===// 9c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall// 10c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall// This file implements the actions class which performs semantic analysis and 11c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall// builds an AST out of a parse stream. 12c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall// 13c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall//===----------------------------------------------------------------------===// 14c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall 15c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall#include "Sema.h" 16c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall#include "clang/AST/ASTContext.h" 17c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall#include "clang/AST/DeclObjC.h" 18c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall#include "clang/AST/Expr.h" 19c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall#include "clang/Lex/Preprocessor.h" 20c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall#include "clang/Basic/Diagnostic.h" 21c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall 22c373d48502ca7683ab55385f5bd624d778eb288dJohn McCallusing namespace clang; 23c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall 24c373d48502ca7683ab55385f5bd624d778eb288dJohn McCallbool Sema::isBuiltinObjCType(TypedefDecl *TD) { 25c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall const char *typeName = TD->getIdentifier()->getName(); 266b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall return strcmp(typeName, "id") == 0 || strcmp(typeName, "Class") == 0 || 276b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall strcmp(typeName, "SEL") == 0 || strcmp(typeName, "Protocol") == 0; 28c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall} 29c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall 306b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallvoid Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) { 316b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall TUScope = S; 32c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall CurContext = Context.getTranslationUnitDecl(); 33c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall if (!PP.getLangOptions().ObjC1) return; 345357b615364c17ea024c757354c58ae2a520d216John McCall 355357b615364c17ea024c757354c58ae2a520d216John McCall // Synthesize "typedef struct objc_selector *SEL;" 365357b615364c17ea024c757354c58ae2a520d216John McCall RecordDecl *SelTag = RecordDecl::Create(Context, TagDecl::TK_struct, 375357b615364c17ea024c757354c58ae2a520d216John McCall CurContext, 385357b615364c17ea024c757354c58ae2a520d216John McCall SourceLocation(), 395357b615364c17ea024c757354c58ae2a520d216John McCall &Context.Idents.get("objc_selector"), 405357b615364c17ea024c757354c58ae2a520d216John McCall 0); 4141d8903731782ee85ee2b19734008b006e01c76fJohn McCall PushOnScopeChains(SelTag, TUScope); 42233a6419097ed97b67ff8efcacef9af613262ca3John McCall 43233a6419097ed97b67ff8efcacef9af613262ca3John McCall QualType SelT = Context.getPointerType(Context.getTagDeclType(SelTag)); 445357b615364c17ea024c757354c58ae2a520d216John McCall TypedefDecl *SelTypedef = TypedefDecl::Create(Context, CurContext, 455357b615364c17ea024c757354c58ae2a520d216John McCall SourceLocation(), 465357b615364c17ea024c757354c58ae2a520d216John McCall &Context.Idents.get("SEL"), 4741d8903731782ee85ee2b19734008b006e01c76fJohn McCall SelT, 0); 48233a6419097ed97b67ff8efcacef9af613262ca3John McCall PushOnScopeChains(SelTypedef, TUScope); 49233a6419097ed97b67ff8efcacef9af613262ca3John McCall Context.setObjCSelType(SelTypedef); 505357b615364c17ea024c757354c58ae2a520d216John McCall 515357b615364c17ea024c757354c58ae2a520d216John McCall // FIXME: Make sure these don't leak! 525357b615364c17ea024c757354c58ae2a520d216John McCall RecordDecl *ClassTag = RecordDecl::Create(Context, TagDecl::TK_struct, 5341d8903731782ee85ee2b19734008b006e01c76fJohn McCall CurContext, 545357b615364c17ea024c757354c58ae2a520d216John McCall SourceLocation(), 55233a6419097ed97b67ff8efcacef9af613262ca3John McCall &Context.Idents.get("objc_class"), 56233a6419097ed97b67ff8efcacef9af613262ca3John McCall 0); 575357b615364c17ea024c757354c58ae2a520d216John McCall QualType ClassT = Context.getPointerType(Context.getTagDeclType(ClassTag)); 585357b615364c17ea024c757354c58ae2a520d216John McCall TypedefDecl *ClassTypedef = 595357b615364c17ea024c757354c58ae2a520d216John McCall TypedefDecl::Create(Context, CurContext, SourceLocation(), 605357b615364c17ea024c757354c58ae2a520d216John McCall &Context.Idents.get("Class"), ClassT, 0); 615357b615364c17ea024c757354c58ae2a520d216John McCall PushOnScopeChains(ClassTag, TUScope); 625357b615364c17ea024c757354c58ae2a520d216John McCall PushOnScopeChains(ClassTypedef, TUScope); 635357b615364c17ea024c757354c58ae2a520d216John McCall Context.setObjCClassType(ClassTypedef); 645357b615364c17ea024c757354c58ae2a520d216John McCall // Synthesize "@class Protocol; 656b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall ObjCInterfaceDecl *ProtocolDecl = 666b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall ObjCInterfaceDecl::Create(Context, SourceLocation(), 675357b615364c17ea024c757354c58ae2a520d216John McCall &Context.Idents.get("Protocol"), 686b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall SourceLocation(), true); 696b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall Context.setObjCProtoType(Context.getObjCInterfaceType(ProtocolDecl)); 7041d8903731782ee85ee2b19734008b006e01c76fJohn McCall PushOnScopeChains(ProtocolDecl, TUScope); 716b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall 726b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall // Synthesize "typedef struct objc_object { Class isa; } *id;" 736b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall RecordDecl *ObjectTag = 745357b615364c17ea024c757354c58ae2a520d216John McCall RecordDecl::Create(Context, TagDecl::TK_struct, CurContext, 755357b615364c17ea024c757354c58ae2a520d216John McCall SourceLocation(), 765357b615364c17ea024c757354c58ae2a520d216John McCall &Context.Idents.get("objc_object"), 0); 775357b615364c17ea024c757354c58ae2a520d216John McCall QualType ObjT = Context.getPointerType(Context.getTagDeclType(ObjectTag)); 785357b615364c17ea024c757354c58ae2a520d216John McCall PushOnScopeChains(ObjectTag, TUScope); 795357b615364c17ea024c757354c58ae2a520d216John McCall TypedefDecl *IdTypedef = TypedefDecl::Create(Context, CurContext, 80233a6419097ed97b67ff8efcacef9af613262ca3John McCall SourceLocation(), 81233a6419097ed97b67ff8efcacef9af613262ca3John McCall &Context.Idents.get("id"), 826b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall ObjT, 0); 836b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall PushOnScopeChains(IdTypedef, TUScope); 845357b615364c17ea024c757354c58ae2a520d216John McCall Context.setObjCIdType(IdTypedef); 855357b615364c17ea024c757354c58ae2a520d216John McCall} 864f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall 874f9506a27cb6b865bf38beea48eadfa9dc93f510John McCallSema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer) 884f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall : PP(pp), Context(ctxt), Consumer(consumer), CurContext(0) { 894f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall 904f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall // Get IdentifierInfo objects for known functions for which we 919a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson // do extra checking. 924f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall IdentifierTable &IT = PP.getIdentifierTable(); 934f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall 944f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall KnownFunctionIDs[id_printf] = &IT.get("printf"); 954f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall KnownFunctionIDs[id_fprintf] = &IT.get("fprintf"); 966b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall KnownFunctionIDs[id_sprintf] = &IT.get("sprintf"); 974f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall KnownFunctionIDs[id_snprintf] = &IT.get("snprintf"); 989a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson KnownFunctionIDs[id_asprintf] = &IT.get("asprintf"); 9982713174914bdb927a254c5ee188e35fd79c4948Sean Hunt KnownFunctionIDs[id_NSLog] = &IT.get("NSLog"); 100c63d2c8469d6b96712b324f76b4af07e1852313fDouglas Gregor KnownFunctionIDs[id_vsnprintf] = &IT.get("vsnprintf"); 1019a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson KnownFunctionIDs[id_vasprintf] = &IT.get("vasprintf"); 1029a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson KnownFunctionIDs[id_vfprintf] = &IT.get("vfprintf"); 1039a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson KnownFunctionIDs[id_vsprintf] = &IT.get("vsprintf"); 1049a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson KnownFunctionIDs[id_vprintf] = &IT.get("vprintf"); 1059a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson 106711f34adb886cce8ba86c7b1b6513a1eaaf63bb5Anders Carlsson SuperID = &IT.get("super"); 10782713174914bdb927a254c5ee188e35fd79c4948Sean Hunt 108c63d2c8469d6b96712b324f76b4af07e1852313fDouglas Gregor TUScope = 0; 1094f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall if (getLangOptions().CPlusPlus) 1104f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall FieldCollector.reset(new CXXFieldCollector()); 1114f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall} 1124f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall 11358e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall/// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast. 1144f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall/// If there is already an implicit cast, merge into the existing one. 1159c127392efe91dadacbe28ca16b8a9a5fa7990b3Douglas Gregorvoid Sema::ImpCastExprToType(Expr *&Expr, QualType Type) { 1164f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall if (Context.getCanonicalType(Expr->getType()) == 1174f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall Context.getCanonicalType(Type)) return; 1184f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall 11958e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall if (ImplicitCastExpr *ImpCast = dyn_cast<ImplicitCastExpr>(Expr)) 1204f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall ImpCast->setType(Type); 1214f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall else 1229c127392efe91dadacbe28ca16b8a9a5fa7990b3Douglas Gregor Expr = new ImplicitCastExpr(Type, Expr); 12358e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall} 1244f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall 12558e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCallvoid Sema::DeleteExpr(ExprTy *E) { 126ef027fe748894522653558d9475a220482395094John McCall delete static_cast<Expr*>(E); 127ef027fe748894522653558d9475a220482395094John McCall} 128ef027fe748894522653558d9475a220482395094John McCallvoid Sema::DeleteStmt(StmtTy *S) { 129ef027fe748894522653558d9475a220482395094John McCall delete static_cast<Stmt*>(S); 13058e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall} 13158e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall 13258e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall/// ActOnEndOfTranslationUnit - This is called at the very end of the 13358e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall/// translation unit when EOF is reached and all but the top-level scope is 13458e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall/// popped. 13558e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCallvoid Sema::ActOnEndOfTranslationUnit() { 13658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall 13758e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall} 13858e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall 13958e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall 14058e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall//===----------------------------------------------------------------------===// 14158e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall// Helper functions. 14258e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall//===----------------------------------------------------------------------===// 14358e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall 1446c790eac94101407acfd2c664400924cab45c0b1John McCallbool Sema::Diag(SourceLocation Loc, unsigned DiagID) { 145ef027fe748894522653558d9475a220482395094John McCall PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID); 146c63d2c8469d6b96712b324f76b4af07e1852313fDouglas Gregor return true; 147c63d2c8469d6b96712b324f76b4af07e1852313fDouglas Gregor} 148ef027fe748894522653558d9475a220482395094John McCall 149ef027fe748894522653558d9475a220482395094John McCallbool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg) { 150ef027fe748894522653558d9475a220482395094John McCall PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, &Msg, 1); 1516c790eac94101407acfd2c664400924cab45c0b1John McCall return true; 152c63d2c8469d6b96712b324f76b4af07e1852313fDouglas Gregor} 153c63d2c8469d6b96712b324f76b4af07e1852313fDouglas Gregor 154c63d2c8469d6b96712b324f76b4af07e1852313fDouglas Gregorbool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg1, 1554f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall const std::string &Msg2) { 156b05b5f35f114505182b076aa70002843c0669bebJohn McCall std::string MsgArr[] = { Msg1, Msg2 }; 157b05b5f35f114505182b076aa70002843c0669bebJohn McCall PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, MsgArr, 2); 158b05b5f35f114505182b076aa70002843c0669bebJohn McCall return true; 159b05b5f35f114505182b076aa70002843c0669bebJohn McCall} 160b05b5f35f114505182b076aa70002843c0669bebJohn McCall 161b05b5f35f114505182b076aa70002843c0669bebJohn McCallbool Sema::Diag(SourceLocation Loc, unsigned DiagID, SourceRange Range) { 162b05b5f35f114505182b076aa70002843c0669bebJohn McCall PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, 0, 0, &Range,1); 16376ef658c703faf72c00f324fb9edc03169718e3eDouglas Gregor return true; 164b05b5f35f114505182b076aa70002843c0669bebJohn McCall} 165b05b5f35f114505182b076aa70002843c0669bebJohn McCall 166b05b5f35f114505182b076aa70002843c0669bebJohn McCallbool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg, 167b05b5f35f114505182b076aa70002843c0669bebJohn McCall SourceRange Range) { 168b05b5f35f114505182b076aa70002843c0669bebJohn McCall PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, &Msg, 1, &Range,1); 169b05b5f35f114505182b076aa70002843c0669bebJohn McCall return true; 170b05b5f35f114505182b076aa70002843c0669bebJohn McCall} 171b05b5f35f114505182b076aa70002843c0669bebJohn McCall 172b05b5f35f114505182b076aa70002843c0669bebJohn McCallbool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg1, 173b05b5f35f114505182b076aa70002843c0669bebJohn McCall const std::string &Msg2, SourceRange Range) { 174b05b5f35f114505182b076aa70002843c0669bebJohn McCall std::string MsgArr[] = { Msg1, Msg2 }; 175b05b5f35f114505182b076aa70002843c0669bebJohn McCall PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, MsgArr, 2, &Range, 1); 176b05b5f35f114505182b076aa70002843c0669bebJohn McCall return true; 177b05b5f35f114505182b076aa70002843c0669bebJohn McCall} 178b05b5f35f114505182b076aa70002843c0669bebJohn McCall 179b05b5f35f114505182b076aa70002843c0669bebJohn McCallbool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg1, 180b05b5f35f114505182b076aa70002843c0669bebJohn McCall const std::string &Msg2, const std::string &Msg3, 181b05b5f35f114505182b076aa70002843c0669bebJohn McCall SourceRange R1) { 182b05b5f35f114505182b076aa70002843c0669bebJohn McCall std::string MsgArr[] = { Msg1, Msg2, Msg3 }; 183b05b5f35f114505182b076aa70002843c0669bebJohn McCall PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, MsgArr, 3, &R1, 1); 184b05b5f35f114505182b076aa70002843c0669bebJohn McCall return true; 185b05b5f35f114505182b076aa70002843c0669bebJohn McCall} 186b05b5f35f114505182b076aa70002843c0669bebJohn McCall 187b05b5f35f114505182b076aa70002843c0669bebJohn McCallbool Sema::Diag(SourceLocation Loc, unsigned DiagID, 188b05b5f35f114505182b076aa70002843c0669bebJohn McCall SourceRange R1, SourceRange R2) { 189b05b5f35f114505182b076aa70002843c0669bebJohn McCall SourceRange RangeArr[] = { R1, R2 }; 190b05b5f35f114505182b076aa70002843c0669bebJohn McCall PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, 0, 0, RangeArr, 2); 191b05b5f35f114505182b076aa70002843c0669bebJohn McCall return true; 192b05b5f35f114505182b076aa70002843c0669bebJohn McCall} 193b05b5f35f114505182b076aa70002843c0669bebJohn McCall 194b05b5f35f114505182b076aa70002843c0669bebJohn McCallbool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg, 195b05b5f35f114505182b076aa70002843c0669bebJohn McCall SourceRange R1, SourceRange R2) { 196b05b5f35f114505182b076aa70002843c0669bebJohn McCall SourceRange RangeArr[] = { R1, R2 }; 197b05b5f35f114505182b076aa70002843c0669bebJohn McCall PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, &Msg, 1, RangeArr, 2); 198b05b5f35f114505182b076aa70002843c0669bebJohn McCall return true; 199b05b5f35f114505182b076aa70002843c0669bebJohn McCall} 200b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall 201b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCallbool Sema::Diag(SourceLocation Range, unsigned DiagID, const std::string &Msg1, 202b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall const std::string &Msg2, SourceRange R1, SourceRange R2) { 203b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall std::string MsgArr[] = { Msg1, Msg2 }; 204aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall SourceRange RangeArr[] = { R1, R2 }; 205b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall PP.getDiagnostics().Report(PP.getFullLoc(Range),DiagID, MsgArr,2,RangeArr, 2); 206b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall return true; 20706a9f3680d22529a2fcf20c52d71cf221d99d910Douglas Gregor} 208b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall 209f961ea5716867b5e426fb2136edd6d1f04c3a7caSean Huntconst LangOptions &Sema::getLangOptions() const { 210c63d2c8469d6b96712b324f76b4af07e1852313fDouglas Gregor return PP.getLangOptions(); 211b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall} 212b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall 21306a9f3680d22529a2fcf20c52d71cf221d99d910Douglas GregorObjCMethodDecl *Sema::getCurMethodDecl() { 214b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall return dyn_cast<ObjCMethodDecl>(CurContext); 215b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall} 216c63d2c8469d6b96712b324f76b4af07e1852313fDouglas Gregor