diff options
Diffstat (limited to 'clang/include/clang')
-rw-r--r-- | clang/include/clang/AST/Decl.h | 12 | ||||
-rw-r--r-- | clang/include/clang/Basic/LangOptions.h | 2 | ||||
-rw-r--r-- | clang/include/clang/Driver/CC1Options.td | 3 | ||||
-rw-r--r-- | clang/include/clang/Driver/Options.td | 2 | ||||
-rw-r--r-- | clang/include/clang/Parse/Parser.h | 21 | ||||
-rw-r--r-- | clang/include/clang/Sema/Sema.h | 13 |
6 files changed, 51 insertions, 2 deletions
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 9255b280d61..5d2a374f72b 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -1294,6 +1294,7 @@ private: bool IsDeleted : 1; bool IsTrivial : 1; // sunk from CXXMethodDecl bool HasImplicitReturnZero : 1; + bool IsLateTemplateParsed : 1; /// \brief End part of this FunctionDecl's source range. /// @@ -1375,7 +1376,8 @@ protected: IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified), IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false), HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false), - HasImplicitReturnZero(false), EndRangeLoc(NameInfo.getEndLoc()), + HasImplicitReturnZero(false), IsLateTemplateParsed(false), + EndRangeLoc(NameInfo.getEndLoc()), TemplateOrSpecialization(), DNLoc(NameInfo.getInfo()) {} @@ -1458,7 +1460,9 @@ public: /// previous definition); for that information, use getBody. /// FIXME: Should return true if function is deleted or defaulted. However, /// CodeGenModule.cpp uses it, and I don't know if this would break it. - bool isThisDeclarationADefinition() const { return Body; } + bool isThisDeclarationADefinition() const { + return Body || IsLateTemplateParsed; + } void setBody(Stmt *B); void setLazyBody(uint64_t Offset) { Body = Offset; } @@ -1475,6 +1479,10 @@ public: bool isPure() const { return IsPure; } void setPure(bool P = true); + /// Whether this templated function will be late parsed. + bool isLateTemplateParsed() const { return IsLateTemplateParsed; } + void setLateTemplateParsed(bool ILT = true) { IsLateTemplateParsed = ILT; } + /// Whether this function is "trivial" in some specialized C++ senses. /// Can only be true for default constructors, copy constructors, /// copy assignment operators, and destructors. Not meaningful until diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 3a739eaf4ad..91287815cd5 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -130,6 +130,7 @@ public: // testing languages such as OpenCL. unsigned MRTD : 1; // -mrtd calling convention + unsigned DelayedTemplateParsing : 1; // Delayed template parsing private: // We declare multibit enums as unsigned because MSVC insists on making enums @@ -225,6 +226,7 @@ public: NoBitFieldTypeAlign = 0; FakeAddressSpaceMap = 0; MRTD = 0; + DelayedTemplateParsing = 0; ParseUnknownAnytype = 0; } diff --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td index 0c2a077a93f..cef94968d0d 100644 --- a/clang/include/clang/Driver/CC1Options.td +++ b/clang/include/clang/Driver/CC1Options.td @@ -532,6 +532,9 @@ def traditional_cpp : Flag<"-traditional-cpp">, HelpText<"Enable some traditional CPP emulation">; def ffake_address_space_map : Flag<"-ffake-address-space-map">, HelpText<"Use a fake address space map; OpenCL testing purposes only">; +def fdelayed_template_parsing : Flag<"-fdelayed-template-parsing">, + HelpText<"Parse templated function definitions at the end of the " + "translation unit ">; def funknown_anytype : Flag<"-funknown-anytype">, HelpText<"Enable parser support for the __unknown_anytype type; for testing purposes only">; diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 542728f2f11..6374eebb619 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -314,6 +314,7 @@ def fmerge_all_constants : Flag<"-fmerge-all-constants">, Group<f_Group>; def fmessage_length_EQ : Joined<"-fmessage-length=">, Group<f_Group>; def fms_extensions : Flag<"-fms-extensions">, Group<f_Group>; def fmsc_version : Joined<"-fmsc-version=">, Group<f_Group>; +def fdelayed_template_parsing : Flag<"-fdelayed-template-parsing">, Group<f_Group>; def fmudflapth : Flag<"-fmudflapth">, Group<f_Group>; def fmudflap : Flag<"-fmudflap">, Group<f_Group>; def fnested_functions : Flag<"-fnested-functions">, Group<f_Group>; @@ -349,6 +350,7 @@ def fno_lax_vector_conversions : Flag<"-fno-lax-vector-conversions">, Group<f_Gr def fno_math_errno : Flag<"-fno-math-errno">, Group<f_Group>; def fno_merge_all_constants : Flag<"-fno-merge-all-constants">, Group<f_Group>; def fno_ms_extensions : Flag<"-fno-ms-extensions">, Group<f_Group>; +def fno_delayed_template_parsing : Flag<"-fno-delayed-template-parsing">, Group<f_Group>; def fno_objc_default_synthesize_properties : Flag<"-fno-objc-default-synthesize-properties">, Group<f_Group>; def fno_objc_exceptions: Flag<"-fno-objc-exceptions">, Group<f_Group>; diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index efc622cc0dd..0880e5416ee 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -919,6 +919,27 @@ private: SourceRange getSourceRange() const; }; + /// \brief Contains a late templated function. + /// Will be parsed at the end of the translation unit. + struct LateParsedTemplatedFunction { + explicit LateParsedTemplatedFunction(Parser* P, Decl *MD) + : D(MD) {} + + CachedTokens Toks; + + /// \brief The template function declaration to be late parsed. + Decl *D; + }; + + void LexTemplateFunctionForLateParsing(CachedTokens &Toks); + void ParseLateTemplatedFuncDef(LateParsedTemplatedFunction &LMT); + typedef llvm::DenseMap<const FunctionDecl*, LateParsedTemplatedFunction*> + LateParsedTemplateMapT; + LateParsedTemplateMapT LateParsedTemplateMap; + + static void LateTemplateParserCallback(void *P, FunctionDecl *FD); + void LateTemplateParser(FunctionDecl *FD); + Sema::ParsingClassState PushParsingClass(Decl *TagOrTemplate, bool TopLevelClass); void DeallocateParsedClasses(ParsingClass *Class); diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index f42fe3d6108..7cb0ad9970e 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -307,6 +307,16 @@ public: /// and must warn if not used. Only contains the first declaration. llvm::SmallVector<const DeclaratorDecl*, 4> UnusedFileScopedDecls; + /// \brief Callback to the parser to parse templated functions when needed. + typedef void LateTemplateParserCB(void *P, FunctionDecl *FD); + LateTemplateParserCB *LateTemplateParser; + void *OpaqueParser; + + void SetLateTemplateParser(LateTemplateParserCB *LTP, void *P) { + LateTemplateParser = LTP; + OpaqueParser = P; + } + class DelayedDiagnostics; class ParsingDeclState { @@ -2974,11 +2984,14 @@ public: AttributeList *AttrList); void ActOnReenterTemplateScope(Scope *S, Decl *Template); + void ActOnReenterDeclaratorTemplateScope(Scope *S, DeclaratorDecl *D); void ActOnStartDelayedMemberDeclarations(Scope *S, Decl *Record); void ActOnStartDelayedCXXMethodDeclaration(Scope *S, Decl *Method); void ActOnDelayedCXXMethodParameter(Scope *S, Decl *Param); void ActOnFinishDelayedCXXMethodDeclaration(Scope *S, Decl *Method); void ActOnFinishDelayedMemberDeclarations(Scope *S, Decl *Record); + void MarkAsLateParsedTemplate(FunctionDecl *FD, bool Flag = true); + bool IsInsideALocalClassWithinATemplateFunction(); Decl *ActOnStaticAssertDeclaration(SourceLocation StaticAssertLoc, Expr *AssertExpr, |